mirror of
				https://github.com/f-droid/fdroidserver.git
				synced 2025-11-04 14:30:30 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			169 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
 | 
						|
import json
 | 
						|
import os
 | 
						|
import shutil
 | 
						|
import sys
 | 
						|
import tempfile
 | 
						|
import unittest
 | 
						|
from pathlib import Path
 | 
						|
from unittest.mock import patch
 | 
						|
 | 
						|
from fdroidserver import verify
 | 
						|
 | 
						|
TEST_APP_ENTRY = {
 | 
						|
    "1539780240.3885746": {
 | 
						|
        "local": {
 | 
						|
            "file": "unsigned/com.politedroid_6.apk",
 | 
						|
            "packageName": "com.politedroid",
 | 
						|
            "sha256": "70c2f776a2bac38a58a7d521f96ee0414c6f0fb1de973c3ca8b10862a009247d",
 | 
						|
            "timestamp": 1234567.8900000,
 | 
						|
            "versionCode": "6",
 | 
						|
            "versionName": "1.5",
 | 
						|
        },
 | 
						|
        "remote": {
 | 
						|
            "file": "tmp/com.politedroid_6.apk",
 | 
						|
            "packageName": "com.politedroid",
 | 
						|
            "sha256": "70c2f776a2bac38a58a7d521f96ee0414c6f0fb1de973c3ca8b10862a009247d",
 | 
						|
            "timestamp": 1234567.8900000,
 | 
						|
            "versionCode": "6",
 | 
						|
            "versionName": "1.5",
 | 
						|
        },
 | 
						|
        "url": "https://f-droid.org/repo/com.politedroid_6.apk",
 | 
						|
        "verified": True,
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
basedir = Path(__file__).parent
 | 
						|
 | 
						|
 | 
						|
class VerifyTest(unittest.TestCase):
 | 
						|
    def setUp(self):
 | 
						|
        self.tempdir = tempfile.TemporaryDirectory()
 | 
						|
        os.chdir(self.tempdir.name)
 | 
						|
        self.repodir = Path('repo')
 | 
						|
        self.repodir.mkdir()
 | 
						|
        self.apk_reports_json = basedir / 'org.fdroid.fdroid_1019051.apk.json'
 | 
						|
 | 
						|
    def tearDown(self):
 | 
						|
        self.tempdir.cleanup()
 | 
						|
 | 
						|
    def test_get_verified_json_creation(self):
 | 
						|
        self.assertEqual({'packages': {}}, verify.get_verified_json('does-not-exist'))
 | 
						|
 | 
						|
    def test_get_verified_json_existing(self):
 | 
						|
        f = 'verified.json'
 | 
						|
        reports = {'packages': {'placeholder': {}}}
 | 
						|
        with open(f, 'w') as fp:
 | 
						|
            json.dump(reports, fp)
 | 
						|
        self.assertEqual(reports, verify.get_verified_json(f))
 | 
						|
 | 
						|
    def test_get_verified_json_pull_in_one_report(self):
 | 
						|
        shutil.copy(self.apk_reports_json, self.tempdir.name)
 | 
						|
        with open(self.apk_reports_json) as fp:
 | 
						|
            reports = json.load(fp)
 | 
						|
        self.assertEqual(
 | 
						|
            {'packages': {'org.fdroid.fdroid': [reports['1708238023.6572325']]}},
 | 
						|
            verify.get_verified_json('does-not-exist'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_get_verified_json_ignore_corrupt(self):
 | 
						|
        f = 'verified.json'
 | 
						|
        with open(f, 'w') as fp:
 | 
						|
            fp.write("""{"packages": {"placeholder": {""")
 | 
						|
        shutil.copy(self.apk_reports_json, self.tempdir.name)
 | 
						|
        with open(self.apk_reports_json) as fp:
 | 
						|
            reports = json.load(fp)
 | 
						|
        self.assertEqual(
 | 
						|
            {'packages': {'org.fdroid.fdroid': [reports['1708238023.6572325']]}},
 | 
						|
            verify.get_verified_json(f),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_get_verified_json_ignore_apk_reports(self):
 | 
						|
        """When an intact verified.json exists, it should ignore the .apk.json reports."""
 | 
						|
        f = 'verified.json'
 | 
						|
        placeholder = {'packages': {'placeholder': {}}}
 | 
						|
        with open(f, 'w') as fp:
 | 
						|
            json.dump(placeholder, fp)
 | 
						|
        shutil.copy(self.apk_reports_json, self.tempdir.name)
 | 
						|
        with open(self.apk_reports_json) as fp:
 | 
						|
            json.load(fp)
 | 
						|
        self.assertEqual(placeholder, verify.get_verified_json(f))
 | 
						|
 | 
						|
    @unittest.skipIf(sys.byteorder == 'big', 'androguard is not ported to big-endian')
 | 
						|
    @patch('fdroidserver.common.sha256sum')
 | 
						|
    def test_write_json_report(self, sha256sum):
 | 
						|
        sha256sum.return_value = (
 | 
						|
            '70c2f776a2bac38a58a7d521f96ee0414c6f0fb1de973c3ca8b10862a009247d'
 | 
						|
        )
 | 
						|
        os.mkdir('tmp')
 | 
						|
        os.mkdir('unsigned')
 | 
						|
        verified_json = Path('unsigned/verified.json')
 | 
						|
        packageName = 'com.politedroid'
 | 
						|
        apk_name = packageName + '_6.apk'
 | 
						|
        remote_apk = 'tmp/' + apk_name
 | 
						|
        unsigned_apk = 'unsigned/' + apk_name
 | 
						|
        # TODO common.use apk_strip_v1_signatures() on unsigned_apk
 | 
						|
        shutil.copy(basedir / 'repo' / apk_name, remote_apk)
 | 
						|
        shutil.copy(basedir / 'repo' / apk_name, unsigned_apk)
 | 
						|
        url = TEST_APP_ENTRY['1539780240.3885746']['url']
 | 
						|
 | 
						|
        self.assertFalse(verified_json.exists())
 | 
						|
        verify.write_json_report(url, remote_apk, unsigned_apk, {})
 | 
						|
        self.assertTrue(verified_json.exists())
 | 
						|
        # smoke check status JSON
 | 
						|
        with verified_json.open() as fp:
 | 
						|
            firstpass = json.load(fp)
 | 
						|
 | 
						|
        verify.write_json_report(url, remote_apk, unsigned_apk, {})
 | 
						|
        with verified_json.open() as fp:
 | 
						|
            secondpass = json.load(fp)
 | 
						|
 | 
						|
        self.assertEqual(firstpass, secondpass)
 | 
						|
 | 
						|
    @patch('fdroidserver.common.sha256sum')
 | 
						|
    @patch('fdroidserver.verify.write_verified_json', lambda s: s)
 | 
						|
    def test_write_json_report_appid_json(self, sha256sum):
 | 
						|
        sha256sum.return_value = (
 | 
						|
            '70c2f776a2bac38a58a7d521f96ee0414c6f0fb1de973c3ca8b10862a009247d'
 | 
						|
        )
 | 
						|
        os.mkdir('tmp')
 | 
						|
        os.mkdir('unsigned')
 | 
						|
        appid = 'com.politedroid'
 | 
						|
        apk_name = f'{appid}_6.apk'
 | 
						|
        remote_apk = 'tmp/' + apk_name
 | 
						|
        unsigned_apk = 'unsigned/' + apk_name
 | 
						|
        shutil.copy(basedir / 'repo' / apk_name, remote_apk)
 | 
						|
        shutil.copy(basedir / 'repo' / apk_name, unsigned_apk)
 | 
						|
        url = TEST_APP_ENTRY['1539780240.3885746']['url']
 | 
						|
        with open(f'unsigned/{apk_name}.json', 'w') as fp:
 | 
						|
            json.dump(TEST_APP_ENTRY, fp)
 | 
						|
 | 
						|
        # make a fake existing report where the newer one broke verifiability
 | 
						|
        with open(f'unsigned/{appid}_16.apk.json', 'w') as fp:
 | 
						|
            json.dump(
 | 
						|
                {
 | 
						|
                    "1444444444.4444444": {
 | 
						|
                        'local': {'versionCode': 16},
 | 
						|
                        'verified': False,
 | 
						|
                    },
 | 
						|
                    "1333333333.3333333": {
 | 
						|
                        'local': {'versionCode': 16},
 | 
						|
                        'verified': True,
 | 
						|
                    },
 | 
						|
                },
 | 
						|
                fp,
 | 
						|
            )
 | 
						|
 | 
						|
        verify.write_json_report(url, remote_apk, unsigned_apk, {'fake': 'fail'})
 | 
						|
        with open(f'unsigned/{appid}.json') as fp:
 | 
						|
            self.assertEqual(
 | 
						|
                {
 | 
						|
                    'apkReports': [
 | 
						|
                        'unsigned/com.politedroid_6.apk.json',
 | 
						|
                        'unsigned/com.politedroid_16.apk.json',
 | 
						|
                    ],
 | 
						|
                    'lastRunVerified': False,
 | 
						|
                },
 | 
						|
                json.load(fp),
 | 
						|
            )
 |