Skip to content

Commit 33f1b13

Browse files
Merge remote-tracking branch 'upstream/version-12' into version-12
2 parents 65a0cfa + 498e8f7 commit 33f1b13

40 files changed

+376
-101
lines changed

.eslintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
"Cypress": true,
141141
"cy": true,
142142
"it": true,
143+
"describe": true,
143144
"expect": true,
144145
"context": true,
145146
"before": true,

.travis.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ install:
5252
- cd ~
5353
- source ./.nvm/nvm.sh
5454
- nvm install v8.10.0
55-
56-
- git clone https://github.com/frappe/bench --depth 1
57-
- pip install -e ./bench
55+
- pip install -U frappe-bench --only-binary='all'
5856

5957
- bench init frappe-bench --skip-assets --python $(which python) --frappe-path $TRAVIS_BUILD_DIR
6058

frappe/__init__.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
reload(sys)
2424
sys.setdefaultencoding("utf-8")
2525

26-
__version__ = '12.17.0'
26+
__version__ = '12.19.0'
2727
__title__ = "Frappe Framework"
2828

2929
local = Local()
@@ -1559,6 +1559,23 @@ def safe_eval(code, eval_globals=None, eval_locals=None):
15591559
"round": round
15601560
}
15611561

1562+
UNSAFE_ATTRIBUTES = {
1563+
# Generator Attributes
1564+
"gi_frame", "gi_code",
1565+
# Coroutine Attributes
1566+
"cr_frame", "cr_code", "cr_origin",
1567+
# Async Generator Attributes
1568+
"ag_code", "ag_frame",
1569+
# Traceback Attributes
1570+
"tb_frame", "tb_next",
1571+
# Format Attributes
1572+
"format", "format_map",
1573+
}
1574+
1575+
for attribute in UNSAFE_ATTRIBUTES:
1576+
if attribute in code:
1577+
throw('Illegal rule {0}. Cannot use "{1}"'.format(bold(code), attribute))
1578+
15621579
if '__' in code:
15631580
throw('Illegal rule {0}. Cannot use "__"'.format(bold(code)))
15641581

frappe/app.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,20 @@ def handle_exception(e):
185185
response = None
186186
http_status_code = getattr(e, "http_status_code", 500)
187187
return_as_message = False
188-
189-
if frappe.get_request_header('Accept') and (frappe.local.is_ajax or 'application/json' in frappe.get_request_header('Accept')):
188+
accept_header = frappe.get_request_header("Accept") or ""
189+
respond_as_json = (
190+
frappe.get_request_header('Accept')
191+
and (frappe.local.is_ajax or 'application/json' in accept_header)
192+
or (
193+
frappe.local.request.path.startswith("/api/") and not accept_header.startswith("text")
194+
)
195+
)
196+
197+
if frappe.conf.get('developer_mode'):
198+
# don't fail silently
199+
print(frappe.get_traceback())
200+
201+
if respond_as_json:
190202
# handle ajax responses first
191203
# if the request is ajax, send back the trace or error message
192204
response = frappe.utils.response.report_error(http_status_code)

frappe/auth.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,10 @@ def authenticate(self, user = None, pwd = None):
209209
self.fail(_('Incomplete login details'), user=user)
210210

211211
# Ignore password check if tmp_id is set, 2FA takes care of authentication.
212-
validate_password = not bool(frappe.form_dict.get('tmp_id'))
212+
tmp_id = bool(frappe.form_dict.tmp_id)
213+
enabled = cint(frappe.db.get_single_value('System Settings', 'enable_two_factor_auth', cache=True))
214+
# if tmp_id is set and 2FA is enabled, skip validation by password
215+
validate_password = not (tmp_id and enabled)
213216
user = User.find_by_credentials(user, pwd, validate_password=validate_password)
214217

215218
if not user:

frappe/change_log/v12/v12_18_0.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## Version 12.18.0 Release Notes
2+
3+
### Fixes & Enhancements
4+
5+
- Moving Site folder across different FileSystems failed ([#13033](https://github.com/frappe/frappe/pull/13033))
6+
- Revert naming for custom naming series ([#13178](https://github.com/frappe/frappe/pull/13178))
7+
- Show delete button on portal if user has permission to delete document ([#13183](https://github.com/frappe/frappe/pull/13183))
8+
- Conditionally hide grid Add Row & Add Multiple buttons ([#12960](https://github.com/frappe/frappe/pull/12960))
9+
- Grid Form buttons Insert Above, Insert Below not hidden when can… ([#12906](https://github.com/frappe/frappe/pull/12906))
10+
- Do not skip data in save while using shortcut ([#13181](https://github.com/frappe/frappe/pull/13181))
11+
- Multi currency in print view shows same currency symbol ([#12569](https://github.com/frappe/frappe/pull/12569))
12+
- Reverting of series with a variable ([#12811](https://github.com/frappe/frappe/pull/12811))
13+
- Grid Form buttons Insert Above, Insert Below not hidden when can… ([#12931](https://github.com/frappe/frappe/pull/12931))
14+
- Check if same value is set to avoid unnecessary change triggers ([#12963](https://github.com/frappe/frappe/pull/12963))
15+
- Default values were not triggering change event ([#12975](https://github.com/frappe/frappe/pull/12975))
16+
- Preload URLs breaking for external requests ([#13058](https://github.com/frappe/frappe/pull/13058))
17+
- Forward message action in communication form view not working ([#12800](https://github.com/frappe/frappe/pull/12800))
18+
- Redirect Web Form user directly to success URL, if no amount is due ([#12661](https://github.com/frappe/frappe/pull/12661))
19+
- Check if response contains signature before setting ([#13185](https://github.com/frappe/frappe/pull/13185))
20+
- Replace parseFloat by Number ([#13011](https://github.com/frappe/frappe/pull/13011))
21+
- Only allow user's attachments to show in attachments tree ([#12822](https://github.com/frappe/frappe/pull/12822))

frappe/change_log/v12/v12_19_0.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## Version 12.19.0 Release Notes
2+
3+
### Fixes & Enhancements
4+
5+
- Refresh form section while refreshing the field ([#13355](https://github.com/frappe/frappe/pull/13355))
6+
- Check for 2FA is enabled or not ([#13455](https://github.com/frappe/frappe/pull/13455))
7+
- Tooltip displays correct title (backport #13346) ([#13354](https://github.com/frappe/frappe/pull/13354))
8+
- Expose limited methods of json module ([#13253](https://github.com/frappe/frappe/pull/13253))
9+
- ci: Update Sider config ([#13332](https://github.com/frappe/frappe/pull/13332))
10+
- auto_repeat field check while loading customize form ([#13350](https://github.com/frappe/frappe/pull/13350))
11+
- Restrict access to python's internal attributes ([#13383](https://github.com/frappe/frappe/pull/13383))
12+
- Respond to /api requests as JSON by default (backport #13028) ([#13408](https://github.com/frappe/frappe/pull/13408))
13+
- CSS bug on print format rtl layout ([#13299](https://github.com/frappe/frappe/pull/13299))
14+
- Check if salutation already exists in email body ([#13196](https://github.com/frappe/frappe/pull/13196))

frappe/commands/site.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ def move(dest_dir, site):
513513
site_dump_exists = os.path.exists(final_new_path)
514514
count = int(count or 0) + 1
515515

516-
os.rename(old_path, final_new_path)
516+
shutil.move(old_path, final_new_path)
517517
frappe.destroy()
518518
return final_new_path
519519

frappe/core/doctype/file/file.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -947,10 +947,18 @@ def validate_filename(filename):
947947

948948
@frappe.whitelist()
949949
def get_files_in_folder(folder):
950-
return frappe.db.get_all('File',
950+
attachment_folder = frappe.db.get_value('File',
951+
'Home/Attachments',
952+
['name', 'file_name', 'file_url', 'is_folder', 'modified'],
953+
as_dict=1
954+
)
955+
files = frappe.db.get_list('File',
951956
{ 'folder': folder },
952957
['name', 'file_name', 'file_url', 'is_folder', 'modified']
953958
)
959+
if folder == 'Home' and attachment_folder not in files:
960+
files.insert(0, attachment_folder)
961+
return files
954962

955963
def update_existing_file_docs(doc):
956964
# Update is private and file url of all file docs that point to the same file

frappe/core/doctype/file/test_file.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import os
99
import unittest
1010
from frappe import _
11-
from frappe.core.doctype.file.file import move_file
11+
from frappe.core.doctype.file.file import move_file, get_files_in_folder
1212
from frappe.utils import get_files_path
1313
# test_records = frappe.get_test_records('File')
1414

@@ -390,3 +390,61 @@ def test_parent_directory_validation_in_file_url(self):
390390
file1.reload()
391391
file1.file_url = '/private/files/parent_dir2.txt'
392392
file1.save()
393+
394+
395+
class TestAttachmentsAccess(unittest.TestCase):
396+
397+
def test_attachments_access(self):
398+
399+
frappe.set_user('test4@example.com')
400+
self.attached_to_doctype, self.attached_to_docname = make_test_doc()
401+
402+
frappe.get_doc({
403+
"doctype": "File",
404+
"file_name": 'test_user.txt',
405+
"attached_to_doctype": self.attached_to_doctype,
406+
"attached_to_name": self.attached_to_docname,
407+
"content": 'Testing User'
408+
}).insert()
409+
410+
frappe.get_doc({
411+
"doctype": "File",
412+
"file_name": "test_user_home.txt",
413+
"content": 'User Home',
414+
}).insert()
415+
416+
frappe.set_user('test@example.com')
417+
418+
frappe.get_doc({
419+
"doctype": "File",
420+
"file_name": 'test_system_manager.txt',
421+
"attached_to_doctype": self.attached_to_doctype,
422+
"attached_to_name": self.attached_to_docname,
423+
"content": 'Testing System Manager'
424+
}).insert()
425+
426+
frappe.get_doc({
427+
"doctype": "File",
428+
"file_name": "test_sm_home.txt",
429+
"content": 'System Manager Home',
430+
}).insert()
431+
432+
system_manager_files = [file.file_name for file in get_files_in_folder('Home')]
433+
system_manager_attachments_files = [file.file_name for file in get_files_in_folder('Home/Attachments')]
434+
435+
frappe.set_user('test4@example.com')
436+
user_files = [file.file_name for file in get_files_in_folder('Home')]
437+
user_attachments_files = [file.file_name for file in get_files_in_folder('Home/Attachments')]
438+
439+
self.assertIn('test_sm_home.txt', system_manager_files)
440+
self.assertNotIn('test_sm_home.txt', user_files)
441+
self.assertIn('test_user_home.txt', system_manager_files)
442+
self.assertIn('test_user_home.txt', user_files)
443+
444+
self.assertIn('test_system_manager.txt', system_manager_attachments_files)
445+
self.assertNotIn('test_system_manager.txt', user_attachments_files)
446+
self.assertIn('test_user.txt', system_manager_attachments_files)
447+
self.assertIn('test_user.txt', user_attachments_files)
448+
449+
frappe.set_user('Administrator')
450+
frappe.db.rollback()

0 commit comments

Comments
 (0)