1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-10-03 17:50:11 +02:00

index.TestCase: manually convert to black code format

* switch to `from fdroidserver import common, index, signindex...`
This commit is contained in:
Hans-Christoph Steiner 2023-04-24 12:21:50 +02:00
parent 98decf8cfa
commit c7070b2799
No known key found for this signature in database
GPG Key ID: 3E177817BA1B9BFA
2 changed files with 225 additions and 192 deletions

View File

@ -274,6 +274,7 @@ black:
tests/dump_internal_metadata_format.py tests/dump_internal_metadata_format.py
tests/exception.TestCase tests/exception.TestCase
tests/import_subcommand.TestCase tests/import_subcommand.TestCase
tests/index.TestCase
tests/init.TestCase tests/init.TestCase
tests/install.TestCase tests/install.TestCase
tests/key-tricks.py tests/key-tricks.py

View File

@ -23,13 +23,8 @@ print('localmodule: ' + localmodule)
if localmodule not in sys.path: if localmodule not in sys.path:
sys.path.insert(0, localmodule) sys.path.insert(0, localmodule)
import fdroidserver.common import fdroidserver
import fdroidserver.index from fdroidserver import common, index, publish, signindex, update
import fdroidserver.metadata
import fdroidserver.net
import fdroidserver.signindex
import fdroidserver.publish
from fdroidserver.exception import FDroidException
from testcommon import TmpCwd, mkdtemp from testcommon import TmpCwd, mkdtemp
from pathlib import Path from pathlib import Path
@ -44,7 +39,6 @@ class Options:
class IndexTest(unittest.TestCase): class IndexTest(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.basedir = os.path.join(localmodule, 'tests') cls.basedir = os.path.join(localmodule, 'tests')
@ -59,13 +53,13 @@ class IndexTest(unittest.TestCase):
os.chmod(os.path.join(self.basedir, 'config.py'), 0o600) os.chmod(os.path.join(self.basedir, 'config.py'), 0o600)
os.chdir(self.basedir) # so read_config() can find config.py os.chdir(self.basedir) # so read_config() can find config.py
fdroidserver.common.config = None common.config = None
fdroidserver.common.options = Options common.options = Options
config = fdroidserver.common.read_config(fdroidserver.common.options) config = common.read_config(common.options)
config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner') config['jarsigner'] = common.find_sdk_tools_cmd('jarsigner')
fdroidserver.common.config = config common.config = config
fdroidserver.signindex.config = config signindex.config = config
fdroidserver.update.config = config update.config = config
self._td = mkdtemp() self._td = mkdtemp()
self.testdir = self._td.name self.testdir = self._td.name
@ -75,16 +69,14 @@ class IndexTest(unittest.TestCase):
def _sign_test_index_v1_jar(self): def _sign_test_index_v1_jar(self):
if not os.path.exists(self.index_v1_jar): if not os.path.exists(self.index_v1_jar):
fdroidserver.signindex.sign_index( signindex.sign_index(os.path.dirname(self.index_v1_jar), 'index-v1.json')
os.path.dirname(self.index_v1_jar), 'index-v1.json'
)
def test_get_public_key_from_jar_succeeds(self): def test_get_public_key_from_jar_succeeds(self):
source_dir = os.path.join(self.basedir, 'signindex') source_dir = os.path.join(self.basedir, 'signindex')
for f in ('testy.jar', 'guardianproject.jar'): for f in ('testy.jar', 'guardianproject.jar'):
testfile = os.path.join(source_dir, f) testfile = os.path.join(source_dir, f)
jar = zipfile.ZipFile(testfile) jar = zipfile.ZipFile(testfile)
_, fingerprint = fdroidserver.index.get_public_key_from_jar(jar) _, fingerprint = index.get_public_key_from_jar(jar)
# comparing fingerprints should be sufficient # comparing fingerprints should be sufficient
if f == 'testy.jar': if f == 'testy.jar':
self.assertEqual( self.assertEqual(
@ -99,23 +91,25 @@ class IndexTest(unittest.TestCase):
source_dir = os.path.join(self.basedir, 'signindex') source_dir = os.path.join(self.basedir, 'signindex')
testfile = os.path.join(source_dir, 'unsigned.jar') testfile = os.path.join(source_dir, 'unsigned.jar')
jar = zipfile.ZipFile(testfile) jar = zipfile.ZipFile(testfile)
with self.assertRaises(fdroidserver.index.VerificationException): with self.assertRaises(index.VerificationException):
fdroidserver.index.get_public_key_from_jar(jar) index.get_public_key_from_jar(jar)
def test_download_repo_index_no_fingerprint(self): def test_download_repo_index_no_fingerprint(self):
with self.assertRaises(fdroidserver.index.VerificationException): with self.assertRaises(index.VerificationException):
fdroidserver.index.download_repo_index("http://example.org") index.download_repo_index("http://example.org")
def test_download_repo_index_no_jar(self): def test_download_repo_index_no_jar(self):
with self.assertRaises(requests.exceptions.RequestException): with self.assertRaises(requests.exceptions.RequestException):
fdroidserver.index.download_repo_index( index.download_repo_index("http://example.org?fingerprint=nope")
"http://example.org?fingerprint=nope"
)
def test_get_repo_key_fingerprint(self): def test_get_repo_key_fingerprint(self):
self._sign_test_index_v1_jar() self._sign_test_index_v1_jar()
pubkey, fingerprint = fdroidserver.index.extract_pubkey() pubkey, fingerprint = index.extract_pubkey()
data, public_key, public_key_fingerprint = fdroidserver.index.get_index_from_jar( (
data,
public_key,
public_key_fingerprint,
) = index.get_index_from_jar(
'repo/index-v1.jar', fingerprint, allow_deprecated=True 'repo/index-v1.jar', fingerprint, allow_deprecated=True
) )
self.assertIsNotNone(data) self.assertIsNotNone(data)
@ -123,17 +117,17 @@ class IndexTest(unittest.TestCase):
self.assertIsNotNone(public_key_fingerprint) self.assertIsNotNone(public_key_fingerprint)
def test_get_index_from_jar_with_bad_fingerprint(self): def test_get_index_from_jar_with_bad_fingerprint(self):
pubkey, fingerprint = fdroidserver.index.extract_pubkey() pubkey, fingerprint = index.extract_pubkey()
fingerprint = fingerprint[:-1] + 'G' fingerprint = fingerprint[:-1] + 'G'
with self.assertRaises(fdroidserver.exception.VerificationException): with self.assertRaises(fdroidserver.exception.VerificationException):
fdroidserver.index.get_index_from_jar( index.get_index_from_jar(
'repo/index-v1.jar', fingerprint, allow_deprecated=True 'repo/index-v1.jar', fingerprint, allow_deprecated=True
) )
def test_get_index_from_jar_with_chars_to_be_stripped(self): def test_get_index_from_jar_with_chars_to_be_stripped(self):
self._sign_test_index_v1_jar() self._sign_test_index_v1_jar()
fingerprint = 'NOOOO F4 9A F3 F1 1E FD DF 20 DF FD 70 F5 E3 11 7B 99 76 67 41 67 AD CA 28 0E 6B 19 32 A0 60 1B 26 F6' fingerprint = 'NOOOO F4 9A F3 F1 1E FD DF 20 DF FD 70 F5 E3 11 7B 99 76 67 41 67 AD CA 28 0E 6B 19 32 A0 60 1B 26 F6'
data, public_key, public_key_fingerprint = fdroidserver.index.get_index_from_jar( index.get_index_from_jar(
'repo/index-v1.jar', fingerprint, allow_deprecated=True 'repo/index-v1.jar', fingerprint, allow_deprecated=True
) )
@ -143,9 +137,9 @@ class IndexTest(unittest.TestCase):
etag = '"4de5-54d840ce95cb9"' etag = '"4de5-54d840ce95cb9"'
head.return_value.headers = {'ETag': etag} head.return_value.headers = {'ETag': etag}
index, new_etag = fdroidserver.index.download_repo_index(url, etag=etag) data, new_etag = index.download_repo_index(url, etag=etag)
self.assertIsNone(index) self.assertIsNone(data)
self.assertEqual(etag, new_etag) self.assertEqual(etag, new_etag)
@patch('requests.get') @patch('requests.get')
@ -162,14 +156,14 @@ class IndexTest(unittest.TestCase):
with open(testfile, 'rb') as file: with open(testfile, 'rb') as file:
get.return_value.content = file.read() get.return_value.content = file.read()
index, new_etag = fdroidserver.index.download_repo_index(url, etag=etag) data, new_etag = index.download_repo_index(url, etag=etag)
# assert that the index was retrieved properly # assert that the index was retrieved properly
self.assertEqual('Guardian Project Official Releases', index['repo']['name']) self.assertEqual('Guardian Project Official Releases', data['repo']['name'])
self.assertEqual(GP_FINGERPRINT, index['repo']['fingerprint']) self.assertEqual(GP_FINGERPRINT, data['repo']['fingerprint'])
self.assertTrue(len(index['repo']['pubkey']) > 500) self.assertTrue(len(data['repo']['pubkey']) > 500)
self.assertEqual(10, len(index['apps'])) self.assertEqual(10, len(data['apps']))
self.assertEqual(10, len(index['packages'])) self.assertEqual(10, len(data['packages']))
self.assertEqual('new_etag', new_etag) self.assertEqual('new_etag', new_etag)
@patch('fdroidserver.net.http_get') @patch('fdroidserver.net.http_get')
@ -186,8 +180,8 @@ class IndexTest(unittest.TestCase):
fingerprint_url = 'https://fake.url/fdroid/repo?fingerprint=' + GP_FINGERPRINT fingerprint_url = 'https://fake.url/fdroid/repo?fingerprint=' + GP_FINGERPRINT
slash_url = 'https://fake.url/fdroid/repo//?fingerprint=' + GP_FINGERPRINT slash_url = 'https://fake.url/fdroid/repo//?fingerprint=' + GP_FINGERPRINT
for url in (repo_url, index_url, fingerprint_url, slash_url): for url in (repo_url, index_url, fingerprint_url, slash_url):
_ignored, etag_set_to_url = fdroidserver.index.download_repo_index(url, verify_fingerprint=False) ilist = index.download_repo_index(url, verify_fingerprint=False)
self.assertEqual(index_url, etag_set_to_url) self.assertEqual(index_url, ilist[1]) # etag item used to return URL
@patch('fdroidserver.net.http_get') @patch('fdroidserver.net.http_get')
def test_download_repo_index_v2_url_parsing(self, mock_http_get): def test_download_repo_index_v2_url_parsing(self, mock_http_get):
@ -204,10 +198,8 @@ class IndexTest(unittest.TestCase):
fingerprint_url = 'https://fake.url/fdroid/repo?fingerprint=' + GP_FINGERPRINT fingerprint_url = 'https://fake.url/fdroid/repo?fingerprint=' + GP_FINGERPRINT
slash_url = 'https://fake.url/fdroid/repo//?fingerprint=' + GP_FINGERPRINT slash_url = 'https://fake.url/fdroid/repo//?fingerprint=' + GP_FINGERPRINT
for url in (repo_url, entry_url, index_url, fingerprint_url, slash_url): for url in (repo_url, entry_url, index_url, fingerprint_url, slash_url):
_ignored, etag_set_to_url = fdroidserver.index.download_repo_index_v2( ilist = index.download_repo_index_v2(url, verify_fingerprint=False)
url, verify_fingerprint=False self.assertEqual(entry_url, ilist[1]) # etag item used to return URL
)
self.assertEqual(entry_url, etag_set_to_url)
@patch('fdroidserver.net.http_get') @patch('fdroidserver.net.http_get')
def test_download_repo_index_v2(self, mock_http_get): def test_download_repo_index_v2(self, mock_http_get):
@ -215,22 +207,21 @@ class IndexTest(unittest.TestCase):
f = os.path.basename(url) f = os.path.basename(url)
with open(os.path.join(self.testdir, 'repo', f), 'rb') as fp: with open(os.path.join(self.testdir, 'repo', f), 'rb') as fp:
return (fp.read(), 'fakeetag') return (fp.read(), 'fakeetag')
mock_http_get.side_effect = http_get_def mock_http_get.side_effect = http_get_def
os.chdir(self.testdir) os.chdir(self.testdir)
fdroidserver.signindex.config['keystore'] = os.path.join(self.basedir, 'keystore.jks') signindex.config['keystore'] = os.path.join(self.basedir, 'keystore.jks')
os.mkdir('repo') os.mkdir('repo')
shutil.copy(os.path.join(self.basedir, 'repo', 'entry.json'), 'repo') shutil.copy(os.path.join(self.basedir, 'repo', 'entry.json'), 'repo')
shutil.copy(os.path.join(self.basedir, 'repo', 'index-v2.json'), 'repo') shutil.copy(os.path.join(self.basedir, 'repo', 'index-v2.json'), 'repo')
fdroidserver.signindex.sign_index('repo', 'entry.json') signindex.sign_index('repo', 'entry.json')
repo_url = 'https://fake.url/fdroid/repo' repo_url = 'https://fake.url/fdroid/repo'
entry_url = 'https://fake.url/fdroid/repo/entry.jar' entry_url = 'https://fake.url/fdroid/repo/entry.jar'
index_url = 'https://fake.url/fdroid/repo/index-v2.json' index_url = 'https://fake.url/fdroid/repo/index-v2.json'
fingerprint_url = 'https://fake.url/fdroid/repo?fingerprint=' + GP_FINGERPRINT fingerprint_url = 'https://fake.url/fdroid/repo?fingerprint=' + GP_FINGERPRINT
slash_url = 'https://fake.url/fdroid/repo//?fingerprint=' + GP_FINGERPRINT slash_url = 'https://fake.url/fdroid/repo//?fingerprint=' + GP_FINGERPRINT
for url in (repo_url, entry_url, index_url, fingerprint_url, slash_url): for url in (repo_url, entry_url, index_url, fingerprint_url, slash_url):
data, _ignored = fdroidserver.index.download_repo_index_v2( data, _ignored = index.download_repo_index_v2(url, verify_fingerprint=False)
url, verify_fingerprint=False
)
self.assertEqual(['repo', 'packages'], list(data.keys())) self.assertEqual(['repo', 'packages'], list(data.keys()))
@patch('fdroidserver.net.http_get') @patch('fdroidserver.net.http_get')
@ -239,126 +230,171 @@ class IndexTest(unittest.TestCase):
f = os.path.basename(url) f = os.path.basename(url)
with open(os.path.join(self.testdir, 'repo', f), 'rb') as fp: with open(os.path.join(self.testdir, 'repo', f), 'rb') as fp:
return (fp.read(), 'fakeetag') return (fp.read(), 'fakeetag')
mock_http_get.side_effect = http_get_def mock_http_get.side_effect = http_get_def
os.chdir(self.testdir) os.chdir(self.testdir)
fdroidserver.signindex.config['keystore'] = os.path.join(self.basedir, 'keystore.jks') signindex.config['keystore'] = os.path.join(self.basedir, 'keystore.jks')
os.mkdir('repo') os.mkdir('repo')
shutil.copy(os.path.join(self.basedir, 'repo', 'entry.json'), 'repo') shutil.copy(os.path.join(self.basedir, 'repo', 'entry.json'), 'repo')
shutil.copy(os.path.join(self.basedir, 'repo', 'index-v2.json'), 'repo') shutil.copy(os.path.join(self.basedir, 'repo', 'index-v2.json'), 'repo')
fdroidserver.signindex.sign_index('repo', 'entry.json') signindex.sign_index('repo', 'entry.json')
bad_fp = '0123456789001234567890012345678900123456789001234567890012345678' bad_fp = '0123456789001234567890012345678900123456789001234567890012345678'
bad_fp_url = 'https://fake.url/fdroid/repo?fingerprint=' + bad_fp bad_fp_url = 'https://fake.url/fdroid/repo?fingerprint=' + bad_fp
with self.assertRaises(fdroidserver.exception.VerificationException): with self.assertRaises(fdroidserver.exception.VerificationException):
data, _ignored = fdroidserver.index.download_repo_index_v2(bad_fp_url) data, _ignored = index.download_repo_index_v2(bad_fp_url)
@patch('fdroidserver.net.http_get') @patch('fdroidserver.net.http_get')
def test_download_repo_index_v2_entry_verify(self, mock_http_get): def test_download_repo_index_v2_entry_verify(self, mock_http_get):
def http_get_def(url, etag, timeout): # pylint: disable=unused-argument def http_get_def(url, etag, timeout): # pylint: disable=unused-argument
return (b'not the entry.jar file contents', 'fakeetag') return (b'not the entry.jar file contents', 'fakeetag')
mock_http_get.side_effect = http_get_def mock_http_get.side_effect = http_get_def
url = 'https://fake.url/fdroid/repo?fingerprint=' + GP_FINGERPRINT url = 'https://fake.url/fdroid/repo?fingerprint=' + GP_FINGERPRINT
with self.assertRaises(fdroidserver.exception.VerificationException): with self.assertRaises(fdroidserver.exception.VerificationException):
data, _ignored = fdroidserver.index.download_repo_index_v2(url) data, _ignored = index.download_repo_index_v2(url)
@patch('fdroidserver.net.http_get') @patch('fdroidserver.net.http_get')
def test_download_repo_index_v2_index_verify(self, mock_http_get): def test_download_repo_index_v2_index_verify(self, mock_http_get):
def http_get_def(url, etag, timeout): # pylint: disable=unused-argument def http_get_def(url, etag, timeout): # pylint: disable=unused-argument
return (b'not the index-v2.json file contents', 'fakeetag') return (b'not the index-v2.json file contents', 'fakeetag')
mock_http_get.side_effect = http_get_def mock_http_get.side_effect = http_get_def
os.chdir(self.testdir) os.chdir(self.testdir)
fdroidserver.signindex.config['keystore'] = os.path.join(self.basedir, 'keystore.jks') signindex.config['keystore'] = os.path.join(self.basedir, 'keystore.jks')
os.mkdir('repo') os.mkdir('repo')
shutil.copy(os.path.join(self.basedir, 'repo', 'entry.json'), 'repo') shutil.copy(os.path.join(self.basedir, 'repo', 'entry.json'), 'repo')
shutil.copy(os.path.join(self.basedir, 'repo', 'index-v2.json'), 'repo') shutil.copy(os.path.join(self.basedir, 'repo', 'index-v2.json'), 'repo')
fdroidserver.signindex.sign_index('repo', 'entry.json') signindex.sign_index('repo', 'entry.json')
url = 'https://fake.url/fdroid/repo?fingerprint=' + GP_FINGERPRINT url = 'https://fake.url/fdroid/repo?fingerprint=' + GP_FINGERPRINT
with self.assertRaises(fdroidserver.exception.VerificationException): with self.assertRaises(fdroidserver.exception.VerificationException):
data, _ignored = fdroidserver.index.download_repo_index_v2(url) data, _ignored = index.download_repo_index_v2(url)
def test_v1_sort_packages(self): def test_v1_sort_packages(self):
i = [
i = [{'packageName': 'org.smssecure.smssecure', {
'packageName': 'org.smssecure.smssecure',
'apkName': 'org.smssecure.smssecure_134.apk', 'apkName': 'org.smssecure.smssecure_134.apk',
'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6', 'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6',
'versionCode': 134}, 'versionCode': 134,
{'packageName': 'org.smssecure.smssecure', },
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'org.smssecure.smssecure_134_b30bb97.apk', 'apkName': 'org.smssecure.smssecure_134_b30bb97.apk',
'signer': 'b30bb971af0d134866e158ec748fcd553df97c150f58b0a963190bbafbeb0868', 'signer': 'b30bb971af0d134866e158ec748fcd553df97c150f58b0a963190bbafbeb0868',
'versionCode': 134}, 'versionCode': 134,
{'packageName': 'b075b32b4ef1e8a869e00edb136bd48e34a0382b85ced8628f164d1199584e4e'}, },
{'packageName': '43af70d1aca437c2f9974c4634cc5abe45bdc4d5d71529ac4e553488d3bb3ff6'}, {
{'packageName': 'org.smssecure.smssecure', 'packageName': 'b075b32b4ef1e8a869e00edb136bd48e34a0382b85ced8628f164d1199584e4e'
},
{
'packageName': '43af70d1aca437c2f9974c4634cc5abe45bdc4d5d71529ac4e553488d3bb3ff6'
},
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'org.smssecure.smssecure_135_b30bb97.apk', 'apkName': 'org.smssecure.smssecure_135_b30bb97.apk',
'signer': 'b30bb971af0d134866e158ec748fcd553df97c150f58b0a963190bbafbeb0868', 'signer': 'b30bb971af0d134866e158ec748fcd553df97c150f58b0a963190bbafbeb0868',
'versionCode': 135}, 'versionCode': 135,
{'packageName': 'org.smssecure.smssecure', },
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'org.smssecure.smssecure_135.apk', 'apkName': 'org.smssecure.smssecure_135.apk',
'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6', 'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6',
'versionCode': 135}, 'versionCode': 135,
{'packageName': 'org.smssecure.smssecure', },
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'org.smssecure.smssecure_133.apk', 'apkName': 'org.smssecure.smssecure_133.apk',
'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6', 'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6',
'versionCode': 133}, 'versionCode': 133,
{'packageName': 'org.smssecure.smssecure', },
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'smssecure-weird-version.apk', 'apkName': 'smssecure-weird-version.apk',
'signer': '99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff', 'signer': '99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff',
'versionCode': 133}, 'versionCode': 133,
{'packageName': 'org.smssecure.smssecure', },
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'smssecure-custom.apk', 'apkName': 'smssecure-custom.apk',
'signer': '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', 'signer': '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
'versionCode': 133}, 'versionCode': 133,
{'packageName': 'org.smssecure.smssecure', },
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'smssecure-new-custom.apk', 'apkName': 'smssecure-new-custom.apk',
'signer': '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', 'signer': '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
'versionCode': 135}] 'versionCode': 135,
},
]
o = [{'packageName': '43af70d1aca437c2f9974c4634cc5abe45bdc4d5d71529ac4e553488d3bb3ff6'}, o = [
{'packageName': 'b075b32b4ef1e8a869e00edb136bd48e34a0382b85ced8628f164d1199584e4e'}, {
'packageName': '43af70d1aca437c2f9974c4634cc5abe45bdc4d5d71529ac4e553488d3bb3ff6'
},
{
'packageName': 'b075b32b4ef1e8a869e00edb136bd48e34a0382b85ced8628f164d1199584e4e'
},
# app test data # app test data
# # packages with reproducible developer signature # # packages with reproducible developer signature
{'packageName': 'org.smssecure.smssecure', {
'packageName': 'org.smssecure.smssecure',
'apkName': 'org.smssecure.smssecure_135_b30bb97.apk', 'apkName': 'org.smssecure.smssecure_135_b30bb97.apk',
'signer': 'b30bb971af0d134866e158ec748fcd553df97c150f58b0a963190bbafbeb0868', 'signer': 'b30bb971af0d134866e158ec748fcd553df97c150f58b0a963190bbafbeb0868',
'versionCode': 135}, 'versionCode': 135,
{'packageName': 'org.smssecure.smssecure', },
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'org.smssecure.smssecure_134_b30bb97.apk', 'apkName': 'org.smssecure.smssecure_134_b30bb97.apk',
'signer': 'b30bb971af0d134866e158ec748fcd553df97c150f58b0a963190bbafbeb0868', 'signer': 'b30bb971af0d134866e158ec748fcd553df97c150f58b0a963190bbafbeb0868',
'versionCode': 134}, 'versionCode': 134,
},
# # packages build and signed by fdroid # # packages build and signed by fdroid
{'packageName': 'org.smssecure.smssecure', {
'packageName': 'org.smssecure.smssecure',
'apkName': 'org.smssecure.smssecure_135.apk', 'apkName': 'org.smssecure.smssecure_135.apk',
'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6', 'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6',
'versionCode': 135}, 'versionCode': 135,
{'packageName': 'org.smssecure.smssecure', },
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'org.smssecure.smssecure_134.apk', 'apkName': 'org.smssecure.smssecure_134.apk',
'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6', 'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6',
'versionCode': 134}, 'versionCode': 134,
{'packageName': 'org.smssecure.smssecure', },
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'org.smssecure.smssecure_133.apk', 'apkName': 'org.smssecure.smssecure_133.apk',
'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6', 'signer': 'b33a601a9da97c82e6eb121eb6b90adab561f396602ec4dc8b0019fb587e2af6',
'versionCode': 133}, 'versionCode': 133,
},
# # packages signed with unkown keys # # packages signed with unkown keys
{'packageName': 'org.smssecure.smssecure', {
'packageName': 'org.smssecure.smssecure',
'apkName': 'smssecure-new-custom.apk', 'apkName': 'smssecure-new-custom.apk',
'signer': '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', 'signer': '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
'versionCode': 135}, 'versionCode': 135,
{'packageName': 'org.smssecure.smssecure', },
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'smssecure-custom.apk', 'apkName': 'smssecure-custom.apk',
'signer': '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', 'signer': '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
'versionCode': 133}, 'versionCode': 133,
{'packageName': 'org.smssecure.smssecure', },
{
'packageName': 'org.smssecure.smssecure',
'apkName': 'smssecure-weird-version.apk', 'apkName': 'smssecure-weird-version.apk',
'signer': '99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff', 'signer': '99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff99ff',
'versionCode': 133}] 'versionCode': 133,
},
]
fdroidserver.common.config = {} common.config = {}
fdroidserver.common.fill_config_defaults(fdroidserver.common.config) common.fill_config_defaults(common.config)
fdroidserver.publish.config = fdroidserver.common.config publish.config = common.config
fdroidserver.publish.config['keystorepass'] = '123456' publish.config['keystorepass'] = '123456'
fdroidserver.publish.config['keypass'] = '123456' publish.config['keypass'] = '123456'
fdroidserver.publish.config['keystore'] = os.path.join(os.getcwd(), publish.config['keystore'] = os.path.join(os.getcwd(), 'dummy-keystore.jks')
'dummy-keystore.jks') publish.config['repo_keyalias'] = 'repokey'
fdroidserver.publish.config['repo_keyalias'] = 'repokey'
testsmetadir = os.path.join(os.getcwd(), 'metadata') testsmetadir = os.path.join(os.getcwd(), 'metadata')
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
@ -372,12 +408,12 @@ class IndexTest(unittest.TestCase):
jarfile = 'stats/publishsigkeys.jar' jarfile = 'stats/publishsigkeys.jar'
with zipfile.ZipFile(jarfile, 'w', zipfile.ZIP_DEFLATED) as jar: with zipfile.ZipFile(jarfile, 'w', zipfile.ZIP_DEFLATED) as jar:
jar.writestr('publishsigkeys.json', json.dumps(sigkeyfps)) jar.writestr('publishsigkeys.json', json.dumps(sigkeyfps))
fdroidserver.publish.sign_sig_key_fingerprint_list(jarfile) publish.sign_sig_key_fingerprint_list(jarfile)
with open('config.py', 'w'): with open('config.py', 'w'):
pass pass
fdroidserver.index.v1_sort_packages( index.v1_sort_packages(
i, fdroidserver.common.load_stats_fdroid_signing_key_fingerprints() i, common.load_stats_fdroid_signing_key_fingerprints()
) )
self.maxDiff = None self.maxDiff = None
self.assertEqual(json.dumps(i, indent=2), json.dumps(o, indent=2)) self.assertEqual(json.dumps(i, indent=2), json.dumps(o, indent=2))
@ -396,14 +432,12 @@ class IndexTest(unittest.TestCase):
'version': 12, 'version': 12,
} }
requestsdict = {'install': [], 'uninstall': []} requestsdict = {'install': [], 'uninstall': []}
fdroidserver.common.config['repo_pubkey'] = 'ffffffffffffffffffffffffffffffffff' common.config['repo_pubkey'] = 'ffffffffffffffffffffffffffffffffff'
fdroidserver.index.make_v0({}, [], 'repo', repodict, requestsdict, {}) index.make_v0({}, [], 'repo', repodict, requestsdict, {})
self.assertTrue(os.path.isdir(repo_icons_dir)) self.assertTrue(os.path.isdir(repo_icons_dir))
self.assertTrue( self.assertTrue(
os.path.exists( os.path.exists(
os.path.join( os.path.join(repo_icons_dir, common.default_config['repo_icon'])
repo_icons_dir, fdroidserver.common.default_config['repo_icon']
)
) )
) )
self.assertTrue(os.path.exists(os.path.join('repo', 'index.xml'))) self.assertTrue(os.path.exists(os.path.join('repo', 'index.xml')))
@ -460,15 +494,13 @@ class IndexTest(unittest.TestCase):
'added': datetime.datetime.fromtimestamp(1539122400), 'added': datetime.datetime.fromtimestamp(1539122400),
} }
requestsdict = {'install': [], 'uninstall': []} requestsdict = {'install': [], 'uninstall': []}
fdroidserver.common.config['repo_pubkey'] = 'ffffffffffffffffffffffffffffffffff' common.config['repo_pubkey'] = 'ffffffffffffffffffffffffffffffffff'
fdroidserver.common.config['make_current_version_link'] = True common.config['make_current_version_link'] = True
fdroidserver.index.make_v0(apps, [apk], 'repo', repodict, requestsdict, {}) index.make_v0(apps, [apk], 'repo', repodict, requestsdict, {})
self.assertTrue(os.path.isdir(repo_icons_dir)) self.assertTrue(os.path.isdir(repo_icons_dir))
self.assertTrue( self.assertTrue(
os.path.exists( os.path.exists(
os.path.join( os.path.join(repo_icons_dir, common.default_config['repo_icon'])
repo_icons_dir, fdroidserver.common.default_config['repo_icon']
)
) )
) )
self.assertTrue(os.path.exists(os.path.join('repo', 'index.xml'))) self.assertTrue(os.path.exists(os.path.join('repo', 'index.xml')))
@ -497,19 +529,19 @@ class IndexTest(unittest.TestCase):
} }
requestsdict = {'install': [], 'uninstall': []} requestsdict = {'install': [], 'uninstall': []}
fdroidserver.common.options.nosign = False common.options.nosign = False
with self.assertRaises(fdroidserver.exception.FDroidException): with self.assertRaises(fdroidserver.exception.FDroidException):
fdroidserver.index.make_v0({}, [], 'repo', repodict, requestsdict, {}) index.make_v0({}, [], 'repo', repodict, requestsdict, {})
fdroidserver.common.options.nosign = True common.options.nosign = True
with self.assertRaises(fdroidserver.exception.FDroidException): with self.assertRaises(fdroidserver.exception.FDroidException):
fdroidserver.index.make_v0({}, [], 'repo', repodict, requestsdict, {}) index.make_v0({}, [], 'repo', repodict, requestsdict, {})
fdroidserver.common.config['repo_pubkey'] = 'ffffffffffffffffffffffffffffffffff' common.config['repo_pubkey'] = 'ffffffffffffffffffffffffffffffffff'
self.assertFalse(os.path.exists(os.path.join('repo', 'index.xml'))) self.assertFalse(os.path.exists(os.path.join('repo', 'index.xml')))
self.assertFalse(os.path.exists(os.path.join('repo', 'index_unsigned.jar'))) self.assertFalse(os.path.exists(os.path.join('repo', 'index_unsigned.jar')))
self.assertFalse(os.path.exists(os.path.join('repo', 'index.jar'))) self.assertFalse(os.path.exists(os.path.join('repo', 'index.jar')))
fdroidserver.index.make_v0({}, [], 'repo', repodict, requestsdict, {}) index.make_v0({}, [], 'repo', repodict, requestsdict, {})
self.assertTrue(os.path.exists(os.path.join('repo', 'index.xml'))) self.assertTrue(os.path.exists(os.path.join('repo', 'index.xml')))
self.assertTrue(os.path.exists(os.path.join('repo', 'index_unsigned.jar'))) self.assertTrue(os.path.exists(os.path.join('repo', 'index_unsigned.jar')))
self.assertFalse(os.path.exists(os.path.join('repo', 'index.jar'))) self.assertFalse(os.path.exists(os.path.join('repo', 'index.jar')))
@ -525,7 +557,7 @@ class IndexTest(unittest.TestCase):
{'url': 'http://two/fdroid/repo'}, {'url': 'http://two/fdroid/repo'},
], ],
} }
fdroidserver.index.make_v1({}, [], 'repo', repodict, {}, {}) index.make_v1({}, [], 'repo', repodict, {}, {})
index_v1 = Path('repo/index-v1.json') index_v1 = Path('repo/index-v1.json')
self.assertTrue(index_v1.exists()) self.assertTrue(index_v1.exists())
with index_v1.open() as fp: with index_v1.open() as fp:
@ -543,7 +575,7 @@ class IndexTest(unittest.TestCase):
]: ]:
self.assertEqual( self.assertEqual(
['https://raw.githubusercontent.com/foo/bar/master/fdroid'], ['https://raw.githubusercontent.com/foo/bar/master/fdroid'],
fdroidserver.index.get_mirror_service_urls(url), index.get_mirror_service_urls(url),
) )
@patch.dict(os.environ, clear=True) @patch.dict(os.environ, clear=True)
@ -571,13 +603,13 @@ class IndexTest(unittest.TestCase):
] ]
self.assertEqual( self.assertEqual(
expected, expected,
fdroidserver.index.get_mirror_service_urls(url), index.get_mirror_service_urls(url),
) )
with patch.dict(os.environ, clear=True): with patch.dict(os.environ, clear=True):
os.environ['CI_JOB_ID'] = ci_job_id os.environ['CI_JOB_ID'] = ci_job_id
self.assertEqual( self.assertEqual(
expected + [artifacts_url], expected + [artifacts_url],
fdroidserver.index.get_mirror_service_urls(url), index.get_mirror_service_urls(url),
) )
with patch('fdroidserver.common.GITLAB_COM_PAGES_MAX_SIZE', 10): with patch('fdroidserver.common.GITLAB_COM_PAGES_MAX_SIZE', 10):
expected = [ expected = [
@ -585,13 +617,13 @@ class IndexTest(unittest.TestCase):
] ]
self.assertEqual( self.assertEqual(
expected, expected,
fdroidserver.index.get_mirror_service_urls(url), index.get_mirror_service_urls(url),
) )
with patch.dict(os.environ, clear=True): with patch.dict(os.environ, clear=True):
os.environ['CI_JOB_ID'] = ci_job_id os.environ['CI_JOB_ID'] = ci_job_id
self.assertEqual( self.assertEqual(
expected + [artifacts_url], expected + [artifacts_url],
fdroidserver.index.get_mirror_service_urls(url), index.get_mirror_service_urls(url),
) )
def test_make_website(self): def test_make_website(self):
@ -608,9 +640,9 @@ class IndexTest(unittest.TestCase):
'version': 12, 'version': 12,
} }
fdroidserver.common.config['repo_pubkey'] = 'ffffffffffffffffffffffffffffffffff' common.config['repo_pubkey'] = 'ffffffffffffffffffffffffffffffffff'
fdroidserver.index.make_website([], "repo", repodict) index.make_website([], "repo", repodict)
self.assertTrue(os.path.exists(os.path.join('repo', 'index.html'))) self.assertTrue(os.path.exists(os.path.join('repo', 'index.html')))
self.assertTrue(os.path.exists(os.path.join('repo', 'index.css'))) self.assertTrue(os.path.exists(os.path.join('repo', 'index.css')))
self.assertTrue(os.path.exists(os.path.join('repo', 'index.png'))) self.assertTrue(os.path.exists(os.path.join('repo', 'index.png')))
@ -643,21 +675,20 @@ class IndexTest(unittest.TestCase):
} }
] ]
fdroidserver.index.v1_sort_packages( index.v1_sort_packages(i, common.load_stats_fdroid_signing_key_fingerprints())
i, fdroidserver.common.load_stats_fdroid_signing_key_fingerprints()
)
def test_package_metadata(self): def test_package_metadata(self):
"""A smoke check and format check of index.package_metadata()""" """A smoke check and format check of index.package_metadata()"""
def _kn(key): def _kn(key):
return key[0].lower() + key[1:] return key[0].lower() + key[1:]
apps = fdroidserver.metadata.read_metadata() apps = fdroidserver.metadata.read_metadata()
fdroidserver.update.insert_localized_app_metadata(apps) update.insert_localized_app_metadata(apps)
# smoke check all metadata files # smoke check all metadata files
for appid, app in apps.items(): for appid, app in apps.items():
metadata = fdroidserver.index.package_metadata(app, 'repo') metadata = index.package_metadata(app, 'repo')
for k in ('Description', 'Name', 'Summary', 'video'): for k in ('Description', 'Name', 'Summary', 'video'):
if app.get(k): if app.get(k):
self.assertTrue(isinstance(metadata[_kn(k)], dict)) self.assertTrue(isinstance(metadata[_kn(k)], dict))
@ -668,7 +699,7 @@ class IndexTest(unittest.TestCase):
# make sure these known values were properly parsed and included # make sure these known values were properly parsed and included
appid = 'info.guardianproject.urzip' appid = 'info.guardianproject.urzip'
app = apps[appid] app = apps[appid]
metadata = fdroidserver.index.package_metadata(app, 'repo') metadata = index.package_metadata(app, 'repo')
# files # files
self.assertEqual(36027, metadata['featureGraphic']['en-US']['size']) self.assertEqual(36027, metadata['featureGraphic']['en-US']['size'])
self.assertEqual(1413, metadata['icon']['en-US']['size']) self.assertEqual(1413, metadata['icon']['en-US']['size'])
@ -683,8 +714,8 @@ class IndexTest(unittest.TestCase):
def test_add_mirrors_to_repodict(self): def test_add_mirrors_to_repodict(self):
"""Test based on the contents of tests/config.py""" """Test based on the contents of tests/config.py"""
repodict = {'address': fdroidserver.common.config['repo_url']} repodict = {'address': common.config['repo_url']}
fdroidserver.index.add_mirrors_to_repodict('repo', repodict) index.add_mirrors_to_repodict('repo', repodict)
self.assertEqual( self.assertEqual(
repodict['mirrors'], repodict['mirrors'],
[ [
@ -698,38 +729,39 @@ class IndexTest(unittest.TestCase):
"""Test based on custom contents of config.yml""" """Test based on custom contents of config.yml"""
os.chdir(self.testdir) os.chdir(self.testdir)
repo_url = 'https://example.com/fdroid/repo' repo_url = 'https://example.com/fdroid/repo'
c = {'repo_url': repo_url, 'mirrors': ['http://one/fdroid']}
with open('config.yml', 'w') as fp: with open('config.yml', 'w') as fp:
yaml.dump({'repo_url': repo_url, 'mirrors': ['http://one/fdroid', ]}, fp) yaml.dump(c, fp)
os.system('cat config.yml') os.system('cat config.yml')
fdroidserver.common.config = None common.config = None
fdroidserver.common.read_config(Options) common.read_config(Options)
repodict = {'address': fdroidserver.common.config['repo_url']} repodict = {'address': common.config['repo_url']}
fdroidserver.index.add_mirrors_to_repodict('repo', repodict) index.add_mirrors_to_repodict('repo', repodict)
self.assertEqual( self.assertEqual(
repodict['mirrors'], repodict['mirrors'],
[ [
{'url': 'https://example.com/fdroid/repo', 'isPrimary': True}, {'url': 'https://example.com/fdroid/repo', 'isPrimary': True},
{'url': 'http://one/fdroid/repo'}, {'url': 'http://one/fdroid/repo'},
] ],
) )
def test_no_mirrors_config(self): def test_no_mirrors_config(self):
fdroidserver.common.config = dict() common.config = dict()
repodict = {'address': 'https://example.com/fdroid/repo'} repodict = {'address': 'https://example.com/fdroid/repo'}
fdroidserver.index.add_mirrors_to_repodict('repo', repodict) index.add_mirrors_to_repodict('repo', repodict)
self.assertFalse('mirrors' in repodict) self.assertFalse('mirrors' in repodict)
def test_add_metadata_to_canonical_in_mirrors_config(self): def test_add_metadata_to_canonical_in_mirrors_config(self):
"""It is possible to add extra metadata to the canonical URL""" """It is possible to add extra metadata to the canonical URL"""
fdroidserver.common.config = { common.config = {
'repo_url': 'http://one/fdroid/repo', 'repo_url': 'http://one/fdroid/repo',
'mirrors': [ 'mirrors': [
{'url': 'http://one/fdroid', 'extra': 'data'}, {'url': 'http://one/fdroid', 'extra': 'data'},
{'url': 'http://two/fdroid'}, {'url': 'http://two/fdroid'},
], ],
} }
repodict = {'address': fdroidserver.common.config['repo_url']} repodict = {'address': common.config['repo_url']}
fdroidserver.index.add_mirrors_to_repodict('repo', repodict) index.add_mirrors_to_repodict('repo', repodict)
self.assertEqual( self.assertEqual(
repodict['mirrors'], repodict['mirrors'],
[ [
@ -740,7 +772,7 @@ class IndexTest(unittest.TestCase):
def test_duplicate_primary_in_mirrors_config(self): def test_duplicate_primary_in_mirrors_config(self):
"""There can be only one primary mirror aka canonical URL""" """There can be only one primary mirror aka canonical URL"""
fdroidserver.common.config = { common.config = {
'repo_url': 'http://one/fdroid', 'repo_url': 'http://one/fdroid',
'mirrors': [ 'mirrors': [
{'url': 'http://one/fdroid', 'countryCode': 'SA'}, {'url': 'http://one/fdroid', 'countryCode': 'SA'},
@ -748,16 +780,16 @@ class IndexTest(unittest.TestCase):
{'url': 'http://one/fdroid'}, {'url': 'http://one/fdroid'},
], ],
} }
repodict = {'address': fdroidserver.common.config['repo_url']} repodict = {'address': common.config['repo_url']}
with self.assertRaises(FDroidException): with self.assertRaises(fdroidserver.exception.FDroidException):
fdroidserver.index.add_mirrors_to_repodict('repo', repodict) index.add_mirrors_to_repodict('repo', repodict)
def test_bad_type_in_mirrors_config(self): def test_bad_type_in_mirrors_config(self):
for i in (1, 2.3, b'asdf'): for i in (1, 2.3, b'asdf'):
fdroidserver.common.config = {'mirrors': i} common.config = {'mirrors': i}
repodict = dict() repodict = dict()
with self.assertRaises(FDroidException): with self.assertRaises(fdroidserver.exception.FDroidException):
fdroidserver.index.add_mirrors_to_repodict('repo', repodict) index.add_mirrors_to_repodict('repo', repodict)
if __name__ == "__main__": if __name__ == "__main__":