2015-09-20 00:27:54 +02:00
|
|
|
import json
|
2015-09-24 22:08:08 +02:00
|
|
|
import time
|
2019-03-15 21:06:59 +01:00
|
|
|
import io
|
2015-09-20 00:27:54 +02:00
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
2015-09-24 22:08:08 +02:00
|
|
|
from Crypt import CryptBitcoin
|
2017-06-19 16:13:58 +02:00
|
|
|
from Content.ContentManager import VerifyError, SignError
|
2017-07-14 10:36:18 +02:00
|
|
|
from util.SafeRe import UnsafePatternError
|
2015-09-24 22:08:08 +02:00
|
|
|
|
2015-09-20 00:27:54 +02:00
|
|
|
|
|
|
|
@pytest.mark.usefixtures("resetSettings")
|
|
|
|
class TestContent:
|
2017-07-14 10:35:44 +02:00
|
|
|
privatekey = "5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv"
|
|
|
|
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
def testInclude(self, site):
|
2015-09-20 00:27:54 +02:00
|
|
|
# Rules defined in parent content.json
|
|
|
|
rules = site.content_manager.getRules("data/test_include/content.json")
|
|
|
|
|
|
|
|
assert rules["signers"] == ["15ik6LeBWnACWfaika1xqGapRZ1zh3JpCo"] # Valid signer
|
|
|
|
assert rules["user_name"] == "test" # Extra data
|
|
|
|
assert rules["max_size"] == 20000 # Max size of files
|
|
|
|
assert not rules["includes_allowed"] # Don't allow more includes
|
|
|
|
assert rules["files_allowed"] == "data.json" # Allowed file pattern
|
|
|
|
|
|
|
|
# Valid signers for "data/test_include/content.json"
|
|
|
|
valid_signers = site.content_manager.getValidSigners("data/test_include/content.json")
|
|
|
|
assert "15ik6LeBWnACWfaika1xqGapRZ1zh3JpCo" in valid_signers # Extra valid signer defined in parent content.json
|
|
|
|
assert "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT" in valid_signers # The site itself
|
|
|
|
assert len(valid_signers) == 2 # No more
|
|
|
|
|
|
|
|
# Valid signers for "data/users/content.json"
|
|
|
|
valid_signers = site.content_manager.getValidSigners("data/users/content.json")
|
|
|
|
assert "1LSxsKfC9S9TVXGGNSM3vPHjyW82jgCX5f" in valid_signers # Extra valid signer defined in parent content.json
|
|
|
|
assert "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT" in valid_signers # The site itself
|
|
|
|
assert len(valid_signers) == 2
|
|
|
|
|
|
|
|
# Valid signers for root content.json
|
|
|
|
assert site.content_manager.getValidSigners("content.json") == ["1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT"]
|
|
|
|
|
2019-03-16 01:00:49 +01:00
|
|
|
def testInlcudeLimits(self, site, crypt_bitcoin_lib):
|
2015-09-20 00:27:54 +02:00
|
|
|
# Data validation
|
2019-03-20 00:46:57 +01:00
|
|
|
res = []
|
2015-09-20 00:27:54 +02:00
|
|
|
data_dict = {
|
|
|
|
"files": {
|
|
|
|
"data.json": {
|
|
|
|
"sha512": "369d4e780cc80504285f13774ca327fe725eed2d813aad229e62356b07365906",
|
|
|
|
"size": 505
|
|
|
|
}
|
|
|
|
},
|
2015-09-24 22:08:08 +02:00
|
|
|
"modified": time.time()
|
2015-09-20 00:27:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Normal data
|
2019-03-20 00:46:57 +01:00
|
|
|
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)}
|
|
|
|
data_json = json.dumps(data_dict).encode()
|
|
|
|
data = io.BytesIO(data_json)
|
2015-09-20 00:27:54 +02:00
|
|
|
assert site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False)
|
2019-03-20 00:46:57 +01:00
|
|
|
|
2015-09-24 22:08:08 +02:00
|
|
|
# Reset
|
|
|
|
del data_dict["signs"]
|
2015-09-20 00:27:54 +02:00
|
|
|
|
|
|
|
# Too large
|
|
|
|
data_dict["files"]["data.json"]["size"] = 200000 # Emulate 2MB sized data.json
|
2019-03-20 00:46:57 +01:00
|
|
|
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)}
|
|
|
|
data = io.BytesIO(json.dumps(data_dict).encode())
|
2017-06-19 16:13:58 +02:00
|
|
|
with pytest.raises(VerifyError) as err:
|
|
|
|
site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False)
|
2019-07-03 18:36:41 +02:00
|
|
|
assert "Include too large" in str(err.value)
|
2017-06-19 16:13:58 +02:00
|
|
|
|
2015-09-24 22:08:08 +02:00
|
|
|
# Reset
|
|
|
|
data_dict["files"]["data.json"]["size"] = 505
|
|
|
|
del data_dict["signs"]
|
2015-09-20 00:27:54 +02:00
|
|
|
|
|
|
|
# Not allowed file
|
|
|
|
data_dict["files"]["notallowed.exe"] = data_dict["files"]["data.json"]
|
2019-03-20 00:46:57 +01:00
|
|
|
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)}
|
|
|
|
data = io.BytesIO(json.dumps(data_dict).encode())
|
2017-06-19 16:13:58 +02:00
|
|
|
with pytest.raises(VerifyError) as err:
|
|
|
|
site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False)
|
2019-07-03 18:36:41 +02:00
|
|
|
assert "File not allowed" in str(err.value)
|
2017-06-19 16:13:58 +02:00
|
|
|
|
2015-09-24 22:08:08 +02:00
|
|
|
# Reset
|
|
|
|
del data_dict["files"]["notallowed.exe"]
|
|
|
|
del data_dict["signs"]
|
2015-09-20 00:27:54 +02:00
|
|
|
|
|
|
|
# Should work again
|
2019-03-20 00:46:57 +01:00
|
|
|
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)}
|
|
|
|
data = io.BytesIO(json.dumps(data_dict).encode())
|
2015-09-20 00:27:54 +02:00
|
|
|
assert site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False)
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
|
|
|
|
@pytest.mark.parametrize("inner_path", ["content.json", "data/test_include/content.json", "data/users/content.json"])
|
|
|
|
def testSign(self, site, inner_path):
|
|
|
|
# Bad privatekey
|
2017-06-19 16:13:58 +02:00
|
|
|
with pytest.raises(SignError) as err:
|
|
|
|
site.content_manager.sign(inner_path, privatekey="5aaa3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMnaa", filewrite=False)
|
2019-07-03 18:36:41 +02:00
|
|
|
assert "Private key invalid" in str(err.value)
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
|
|
|
|
# Good privatekey
|
2017-07-14 10:35:44 +02:00
|
|
|
content = site.content_manager.sign(inner_path, privatekey=self.privatekey, filewrite=False)
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
content_old = site.content_manager.contents[inner_path] # Content before the sign
|
|
|
|
assert not content_old == content # Timestamp changed
|
|
|
|
assert site.address in content["signs"] # Used the site's private key to sign
|
|
|
|
if inner_path == "content.json":
|
|
|
|
assert len(content["files"]) == 17
|
|
|
|
elif inner_path == "data/test-include/content.json":
|
|
|
|
assert len(content["files"]) == 1
|
|
|
|
elif inner_path == "data/users/content.json":
|
|
|
|
assert len(content["files"]) == 0
|
|
|
|
|
|
|
|
# Everything should be same as before except the modified timestamp and the signs
|
|
|
|
assert (
|
Version 0.3.4, Rev656, CryptMessage plugin for AES and ECIES encryption, Added pyelliptic lib for OpenSSSL based encryption methods, Test CryptMessage plugin, Force reload content.json before signing and after write, Escaped Sql IN queries support, Test Sql parameter escaping, ui_websocket Test fixture, Plugin testing support, Always return websocket errors as dict, Wait for file on weboscket fileGet command if its already in bad_files queue, PushState and ReplaceState url manipulation support in wrapper API, Per auth-address localstorage, Longer timeout for udp tracker query
2015-12-10 21:36:20 +01:00
|
|
|
{key: val for key, val in content_old.items() if key not in ["modified", "signs", "sign", "zeronet_version"]}
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
==
|
Version 0.3.4, Rev656, CryptMessage plugin for AES and ECIES encryption, Added pyelliptic lib for OpenSSSL based encryption methods, Test CryptMessage plugin, Force reload content.json before signing and after write, Escaped Sql IN queries support, Test Sql parameter escaping, ui_websocket Test fixture, Plugin testing support, Always return websocket errors as dict, Wait for file on weboscket fileGet command if its already in bad_files queue, PushState and ReplaceState url manipulation support in wrapper API, Per auth-address localstorage, Longer timeout for udp tracker query
2015-12-10 21:36:20 +01:00
|
|
|
{key: val for key, val in content.items() if key not in ["modified", "signs", "sign", "zeronet_version"]}
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def testSignOptionalFiles(self, site):
|
2016-09-05 13:58:10 +02:00
|
|
|
for hash in list(site.content_manager.hashfield):
|
|
|
|
site.content_manager.hashfield.remove(hash)
|
|
|
|
|
2015-11-02 22:39:19 +01:00
|
|
|
assert len(site.content_manager.hashfield) == 0
|
|
|
|
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
site.content_manager.contents["content.json"]["optional"] = "((data/img/zero.*))"
|
2017-07-14 10:35:44 +02:00
|
|
|
content_optional = site.content_manager.sign(privatekey=self.privatekey, filewrite=False, remove_missing_optional=True)
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
|
|
|
|
del site.content_manager.contents["content.json"]["optional"]
|
2017-07-14 10:35:44 +02:00
|
|
|
content_nooptional = site.content_manager.sign(privatekey=self.privatekey, filewrite=False, remove_missing_optional=True)
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
|
2015-11-02 22:39:19 +01:00
|
|
|
assert len(content_nooptional.get("files_optional", {})) == 0 # No optional files if no pattern
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
assert len(content_optional["files_optional"]) > 0
|
2015-11-02 22:39:19 +01:00
|
|
|
assert len(site.content_manager.hashfield) == len(content_optional["files_optional"]) # Hashed optional files should be added to hashfield
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
assert len(content_nooptional["files"]) > len(content_optional["files"])
|
|
|
|
|
|
|
|
def testFileInfo(self, site):
|
|
|
|
assert "sha512" in site.content_manager.getFileInfo("index.html")
|
2017-10-26 10:50:56 +02:00
|
|
|
assert site.content_manager.getFileInfo("data/img/domain.png")["content_inner_path"] == "content.json"
|
2017-10-04 13:36:14 +02:00
|
|
|
assert site.content_manager.getFileInfo("data/users/hello.png")["content_inner_path"] == "data/users/content.json"
|
|
|
|
assert site.content_manager.getFileInfo("data/users/content.json")["content_inner_path"] == "data/users/content.json"
|
Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
2015-10-01 01:35:13 +02:00
|
|
|
assert not site.content_manager.getFileInfo("notexist")
|
|
|
|
|
|
|
|
# Optional file
|
|
|
|
file_info_optional = site.content_manager.getFileInfo("data/optional.txt")
|
|
|
|
assert "sha512" in file_info_optional
|
|
|
|
assert file_info_optional["optional"] is True
|
|
|
|
|
|
|
|
# Not exists yet user content.json
|
|
|
|
assert "cert_signers" in site.content_manager.getFileInfo("data/users/unknown/content.json")
|
|
|
|
|
|
|
|
# Optional user file
|
|
|
|
file_info_optional = site.content_manager.getFileInfo("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif")
|
|
|
|
assert "sha512" in file_info_optional
|
|
|
|
assert file_info_optional["optional"] is True
|
Rev903, FeedQuery command only available for ADMIN sites, Show bad files in sidebar, Log unknown messages, Add and check inner_path and site address on sign/verify, Better peer cleanup limit, Log site load times, Testcase for address and inner_path verification, Re-sign testsite with new fields, Fix unnecessary loading screen display when browsing sub-folder with index.html, Fix safari notification width
2016-02-18 11:22:21 +01:00
|
|
|
|
2019-03-16 01:00:49 +01:00
|
|
|
def testVerify(self, site, crypt_bitcoin_lib):
|
Rev903, FeedQuery command only available for ADMIN sites, Show bad files in sidebar, Log unknown messages, Add and check inner_path and site address on sign/verify, Better peer cleanup limit, Log site load times, Testcase for address and inner_path verification, Re-sign testsite with new fields, Fix unnecessary loading screen display when browsing sub-folder with index.html, Fix safari notification width
2016-02-18 11:22:21 +01:00
|
|
|
inner_path = "data/test_include/content.json"
|
2016-04-06 13:44:31 +02:00
|
|
|
data_dict = site.storage.loadJson(inner_path)
|
2019-03-16 01:00:49 +01:00
|
|
|
data = io.BytesIO(json.dumps(data_dict).encode("utf8"))
|
Rev903, FeedQuery command only available for ADMIN sites, Show bad files in sidebar, Log unknown messages, Add and check inner_path and site address on sign/verify, Better peer cleanup limit, Log site load times, Testcase for address and inner_path verification, Re-sign testsite with new fields, Fix unnecessary loading screen display when browsing sub-folder with index.html, Fix safari notification width
2016-02-18 11:22:21 +01:00
|
|
|
|
|
|
|
# Re-sign
|
|
|
|
data_dict["signs"] = {
|
2017-07-14 10:35:44 +02:00
|
|
|
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)
|
Rev903, FeedQuery command only available for ADMIN sites, Show bad files in sidebar, Log unknown messages, Add and check inner_path and site address on sign/verify, Better peer cleanup limit, Log site load times, Testcase for address and inner_path verification, Re-sign testsite with new fields, Fix unnecessary loading screen display when browsing sub-folder with index.html, Fix safari notification width
2016-02-18 11:22:21 +01:00
|
|
|
}
|
|
|
|
assert site.content_manager.verifyFile(inner_path, data, ignore_same=False)
|
|
|
|
|
|
|
|
# Wrong address
|
|
|
|
data_dict["address"] = "Othersite"
|
|
|
|
del data_dict["signs"]
|
|
|
|
data_dict["signs"] = {
|
2017-07-14 10:35:44 +02:00
|
|
|
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)
|
Rev903, FeedQuery command only available for ADMIN sites, Show bad files in sidebar, Log unknown messages, Add and check inner_path and site address on sign/verify, Better peer cleanup limit, Log site load times, Testcase for address and inner_path verification, Re-sign testsite with new fields, Fix unnecessary loading screen display when browsing sub-folder with index.html, Fix safari notification width
2016-02-18 11:22:21 +01:00
|
|
|
}
|
2019-03-20 00:46:57 +01:00
|
|
|
data = io.BytesIO(json.dumps(data_dict).encode())
|
2017-06-19 16:13:58 +02:00
|
|
|
with pytest.raises(VerifyError) as err:
|
|
|
|
site.content_manager.verifyFile(inner_path, data, ignore_same=False)
|
2019-07-03 18:36:41 +02:00
|
|
|
assert "Wrong site address" in str(err.value)
|
Rev903, FeedQuery command only available for ADMIN sites, Show bad files in sidebar, Log unknown messages, Add and check inner_path and site address on sign/verify, Better peer cleanup limit, Log site load times, Testcase for address and inner_path verification, Re-sign testsite with new fields, Fix unnecessary loading screen display when browsing sub-folder with index.html, Fix safari notification width
2016-02-18 11:22:21 +01:00
|
|
|
|
|
|
|
# Wrong inner_path
|
|
|
|
data_dict["address"] = "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT"
|
|
|
|
data_dict["inner_path"] = "content.json"
|
|
|
|
del data_dict["signs"]
|
|
|
|
data_dict["signs"] = {
|
2017-07-14 10:35:44 +02:00
|
|
|
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)
|
Rev903, FeedQuery command only available for ADMIN sites, Show bad files in sidebar, Log unknown messages, Add and check inner_path and site address on sign/verify, Better peer cleanup limit, Log site load times, Testcase for address and inner_path verification, Re-sign testsite with new fields, Fix unnecessary loading screen display when browsing sub-folder with index.html, Fix safari notification width
2016-02-18 11:22:21 +01:00
|
|
|
}
|
2019-03-20 00:46:57 +01:00
|
|
|
data = io.BytesIO(json.dumps(data_dict).encode())
|
2017-06-19 16:13:58 +02:00
|
|
|
with pytest.raises(VerifyError) as err:
|
|
|
|
site.content_manager.verifyFile(inner_path, data, ignore_same=False)
|
2019-07-03 18:36:41 +02:00
|
|
|
assert "Wrong inner_path" in str(err.value)
|
Rev903, FeedQuery command only available for ADMIN sites, Show bad files in sidebar, Log unknown messages, Add and check inner_path and site address on sign/verify, Better peer cleanup limit, Log site load times, Testcase for address and inner_path verification, Re-sign testsite with new fields, Fix unnecessary loading screen display when browsing sub-folder with index.html, Fix safari notification width
2016-02-18 11:22:21 +01:00
|
|
|
|
|
|
|
# Everything right again
|
|
|
|
data_dict["address"] = "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT"
|
|
|
|
data_dict["inner_path"] = inner_path
|
|
|
|
del data_dict["signs"]
|
|
|
|
data_dict["signs"] = {
|
2017-07-14 10:35:44 +02:00
|
|
|
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)
|
Rev903, FeedQuery command only available for ADMIN sites, Show bad files in sidebar, Log unknown messages, Add and check inner_path and site address on sign/verify, Better peer cleanup limit, Log site load times, Testcase for address and inner_path verification, Re-sign testsite with new fields, Fix unnecessary loading screen display when browsing sub-folder with index.html, Fix safari notification width
2016-02-18 11:22:21 +01:00
|
|
|
}
|
2019-03-20 00:46:57 +01:00
|
|
|
data = io.BytesIO(json.dumps(data_dict).encode())
|
Rev903, FeedQuery command only available for ADMIN sites, Show bad files in sidebar, Log unknown messages, Add and check inner_path and site address on sign/verify, Better peer cleanup limit, Log site load times, Testcase for address and inner_path verification, Re-sign testsite with new fields, Fix unnecessary loading screen display when browsing sub-folder with index.html, Fix safari notification width
2016-02-18 11:22:21 +01:00
|
|
|
assert site.content_manager.verifyFile(inner_path, data, ignore_same=False)
|
2017-07-13 19:33:07 +02:00
|
|
|
|
2019-03-16 01:00:49 +01:00
|
|
|
def testVerifyInnerPath(self, site, crypt_bitcoin_lib):
|
2017-07-13 19:33:07 +02:00
|
|
|
inner_path = "content.json"
|
|
|
|
data_dict = site.storage.loadJson(inner_path)
|
|
|
|
|
2019-11-07 02:47:19 +01:00
|
|
|
for good_relative_path in ["data.json", "out/data.json", "Any File [by none] (1).jpg", "árvzítűrő/tükörfúrógép.txt"]:
|
2017-07-13 19:33:07 +02:00
|
|
|
data_dict["files"] = {good_relative_path: {"sha512": "369d4e780cc80504285f13774ca327fe725eed2d813aad229e62356b07365906", "size": 505}}
|
|
|
|
|
|
|
|
if "sign" in data_dict:
|
|
|
|
del data_dict["sign"]
|
|
|
|
del data_dict["signs"]
|
|
|
|
data_dict["signs"] = {
|
2017-07-14 10:35:44 +02:00
|
|
|
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)
|
2017-07-13 19:33:07 +02:00
|
|
|
}
|
2019-03-20 00:46:57 +01:00
|
|
|
data = io.BytesIO(json.dumps(data_dict).encode())
|
2017-07-13 19:33:07 +02:00
|
|
|
assert site.content_manager.verifyFile(inner_path, data, ignore_same=False)
|
|
|
|
|
2019-11-07 02:47:19 +01:00
|
|
|
for bad_relative_path in ["../data.json", "data/" * 100, "invalid|file.jpg", "con.txt", "any/con.txt"]:
|
2017-07-13 19:33:07 +02:00
|
|
|
data_dict["files"] = {bad_relative_path: {"sha512": "369d4e780cc80504285f13774ca327fe725eed2d813aad229e62356b07365906", "size": 505}}
|
|
|
|
|
|
|
|
if "sign" in data_dict:
|
|
|
|
del data_dict["sign"]
|
|
|
|
del data_dict["signs"]
|
|
|
|
data_dict["signs"] = {
|
2017-07-14 10:35:44 +02:00
|
|
|
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)
|
2017-07-13 19:33:07 +02:00
|
|
|
}
|
2019-03-20 00:46:57 +01:00
|
|
|
data = io.BytesIO(json.dumps(data_dict).encode())
|
2017-07-13 19:33:07 +02:00
|
|
|
with pytest.raises(VerifyError) as err:
|
|
|
|
site.content_manager.verifyFile(inner_path, data, ignore_same=False)
|
2019-07-03 18:36:41 +02:00
|
|
|
assert "Invalid relative path" in str(err.value)
|
2017-07-13 19:33:07 +02:00
|
|
|
|
2017-07-14 10:36:18 +02:00
|
|
|
@pytest.mark.parametrize("key", ["ignore", "optional"])
|
|
|
|
def testSignUnsafePattern(self, site, key):
|
|
|
|
site.content_manager.contents["content.json"][key] = "([a-zA-Z]+)*"
|
|
|
|
with pytest.raises(UnsafePatternError) as err:
|
|
|
|
site.content_manager.sign("content.json", privatekey=self.privatekey, filewrite=False)
|
2019-07-03 18:36:41 +02:00
|
|
|
assert "Potentially unsafe" in str(err.value)
|
2017-07-14 10:36:18 +02:00
|
|
|
|
|
|
|
|
2019-03-16 01:00:49 +01:00
|
|
|
def testVerifyUnsafePattern(self, site, crypt_bitcoin_lib):
|
2017-07-14 10:36:18 +02:00
|
|
|
site.content_manager.contents["content.json"]["includes"]["data/test_include/content.json"]["files_allowed"] = "([a-zA-Z]+)*"
|
|
|
|
with pytest.raises(UnsafePatternError) as err:
|
2017-10-04 13:35:55 +02:00
|
|
|
with site.storage.open("data/test_include/content.json") as data:
|
|
|
|
site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False)
|
2019-07-03 18:36:41 +02:00
|
|
|
assert "Potentially unsafe" in str(err.value)
|
2017-07-14 10:36:18 +02:00
|
|
|
|
|
|
|
site.content_manager.contents["data/users/content.json"]["user_contents"]["permission_rules"]["([a-zA-Z]+)*"] = {"max_size": 0}
|
|
|
|
with pytest.raises(UnsafePatternError) as err:
|
2017-10-04 13:35:55 +02:00
|
|
|
with site.storage.open("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json") as data:
|
|
|
|
site.content_manager.verifyFile("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json", data, ignore_same=False)
|
2019-07-03 18:36:41 +02:00
|
|
|
assert "Potentially unsafe" in str(err.value)
|
2019-11-07 02:18:27 +01:00
|
|
|
|
|
|
|
def testPathValidation(self, site):
|
|
|
|
assert site.content_manager.isValidRelativePath("test.txt")
|
|
|
|
assert site.content_manager.isValidRelativePath("test/!@#$%^&().txt")
|
|
|
|
assert site.content_manager.isValidRelativePath("ÜøßÂŒƂÆÇ.txt")
|
|
|
|
assert site.content_manager.isValidRelativePath("тест.текст")
|
|
|
|
assert site.content_manager.isValidRelativePath("𝐮𝐧𝐢𝐜𝐨𝐝𝐞𝑖𝑠𝒂𝒘𝒆𝒔𝒐𝒎𝒆")
|
|
|
|
|
2019-11-07 02:47:19 +01:00
|
|
|
# Test rules based on https://stackoverflow.com/questions/1976007/what-characters-are-forbidden-in-windows-and-linux-directory-names
|
|
|
|
|
|
|
|
assert not site.content_manager.isValidRelativePath("any\\hello.txt") # \ not allowed
|
|
|
|
assert not site.content_manager.isValidRelativePath("/hello.txt") # Cannot start with /
|
|
|
|
assert not site.content_manager.isValidRelativePath("../hello.txt") # Not allowed .. in path
|
|
|
|
assert not site.content_manager.isValidRelativePath("\0hello.txt") # NULL character
|
|
|
|
assert not site.content_manager.isValidRelativePath("\31hello.txt") # 0-31 (ASCII control characters)
|
|
|
|
assert not site.content_manager.isValidRelativePath("any/hello.txt ") # Cannot end with space
|
|
|
|
assert not site.content_manager.isValidRelativePath("any/hello.txt.") # Cannot end with dot
|
|
|
|
assert not site.content_manager.isValidRelativePath("any/CON") # Protected names on Windows
|
|
|
|
assert not site.content_manager.isValidRelativePath("CON/any.txt")
|
|
|
|
assert not site.content_manager.isValidRelativePath("any/lpt1.txt")
|
|
|
|
assert site.content_manager.isValidRelativePath("any/CONAN")
|
|
|
|
assert not site.content_manager.isValidRelativePath("any/CONOUT$")
|
|
|
|
assert not site.content_manager.isValidRelativePath("a" * 256) # Max 255 characters allowed
|