Skip to content

Commit 23de44a

Browse files
nglevinluispadron
authored andcommitted
Remove the unused subcommands of the Python dossier code signing tool.
Cherry-pick: 0aa0d31
1 parent b2868a9 commit 23de44a

2 files changed

Lines changed: 1 addition & 649 deletions

File tree

tools/dossier_codesigningtool/dossier_codesigningtool.py

Lines changed: 1 addition & 303 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,11 @@
1919
import json
2020
import os
2121
import os.path
22-
import plistlib
23-
import re
2422
import shutil
2523
import subprocess
2624
import sys
2725
import tempfile
28-
from typing import Dict, List, Optional, Tuple, Union
26+
from typing import Dict, List, Optional, Union
2927
import uuid
3028

3129
from tools.dossier_codesigningtool import dossier_codesigning_reader as dossier_reader
@@ -34,57 +32,13 @@
3432
_ManifestJsonValue = Union[str, List[str], Dict[str, str]]
3533

3634

37-
class DossierDirectory(object):
38-
"""Class to manage dossier directories.
39-
40-
Must used as a context manager.
41-
42-
Attributes:
43-
path: The string path to the directory.
44-
unzipped: A boolean indicating if the dossier was unzipped or already was a
45-
directory.
46-
"""
47-
48-
def __init__(self, path, unzipped):
49-
self.path = path
50-
self.unzipped = unzipped
51-
52-
def __enter__(self):
53-
return self
54-
55-
def __exit__(self, exception_type, exception_value, traceback):
56-
if self.unzipped:
57-
shutil.rmtree(self.path)
58-
59-
60-
# Directories within a bundle that embedded bundles may be present in.
61-
_EMBEDDED_BUNDLE_DIRECTORY_NAMES = [
62-
'AppClips', 'Extensions', 'PlugIns', 'Frameworks', 'Watch'
63-
]
64-
65-
6635
def generate_arg_parser():
6736
"""Generates an argument parser for this tool."""
6837
parser = argparse.ArgumentParser(
6938
description='Tool for generating dossiers for signing iOS bundles.',
7039
fromfile_prefix_chars='@')
7140
subparsers = parser.add_subparsers(help='Sub-commands')
7241

73-
generate_parser = subparsers.add_parser(
74-
'generate', help='Generate a dossier from a signed bundle.')
75-
generate_parser.add_argument(
76-
'--output',
77-
required=True,
78-
help='Path to output manifest dossier location.')
79-
generate_parser.add_argument(
80-
'--zip',
81-
action='store_true',
82-
help='Zip the final dossier into a file at specified location.')
83-
generate_parser.add_argument(
84-
'--codesign', required=True, type=str, help='Path to codesign binary')
85-
generate_parser.add_argument('bundle', help='Path to the bundle')
86-
generate_parser.set_defaults(func=_generate_manifest_dossier)
87-
8842
create_parser = subparsers.add_parser('create', help='Create a dossier.')
8943
create_parser.add_argument(
9044
'--output',
@@ -127,88 +81,9 @@ def generate_arg_parser():
12781
)
12882
create_parser.set_defaults(func=_create_dossier)
12983

130-
embed_parser = subparsers.add_parser(
131-
'embed',
132-
help=(
133-
'Embeds a dossier into an existing dossier. Only supports embedding'
134-
' at the top level of the existing dossier.'
135-
),
136-
)
137-
embed_parser.add_argument(
138-
'--dossier', required=True, help='Path to dossier location to edit.')
139-
embed_parser.add_argument(
140-
'--embedded_relative_artifact_path',
141-
required=True,
142-
type=str,
143-
help='Relative path of artifact the dossier to be embedded signs')
144-
embed_parser.add_argument(
145-
'--embedded_dossier_path',
146-
required=True,
147-
type=str,
148-
help='Path to dossier to be embedded')
149-
embed_parser.set_defaults(func=_embed_dossier)
150-
15184
return parser
15285

15386

154-
def _extract_codesign_data(
155-
bundle_path: str,
156-
output_directory: str,
157-
unique_id: str,
158-
codesign_path: str) -> Tuple[Optional[str], Optional[str]]:
159-
"""Extracts codesigning data from the provided bundle to the output directory.
160-
161-
Given a bundle_path will extract the entitlements file to the provided
162-
output_directory as well as extract the codesigning identity.
163-
164-
Args:
165-
bundle_path: The absolute path to the bundle to extract entitlements from.
166-
output_directory: The absolute path to the output directory the entitlements
167-
should be placed in, it must already exist.
168-
unique_id: Unique identifier to use for filename of extracted entitlements.
169-
codesign_path: Path to the codesign tool as a string.
170-
171-
Returns:
172-
A tuple of the output file name for the entitlements in the output_directory
173-
and the codesigning identity. If either of these is not available, they will
174-
be set to None in the tuple.
175-
176-
Raises:
177-
OSError: If unable to extract codesign identity.
178-
"""
179-
command = (codesign_path, '-dvv', '--entitlements', ':-', bundle_path)
180-
process = subprocess.Popen(
181-
command,
182-
stdout=subprocess.PIPE,
183-
stderr=subprocess.PIPE,
184-
encoding='utf8',
185-
errors='replace')
186-
output, stderr = process.communicate()
187-
if process.poll() != 0:
188-
raise OSError('Fail to extract entitlements from bundle: %s' % stderr)
189-
190-
if not output:
191-
return None, None
192-
193-
signing_info = re.search(r'^Authority=(.*)$', str(stderr), re.MULTILINE)
194-
if signing_info:
195-
cert_authority = signing_info.group(1)
196-
else:
197-
cert_authority = None
198-
199-
plist = plistlib.loads(output.encode('utf-8'))
200-
if not plist:
201-
return None, cert_authority
202-
203-
output_file_name = unique_id + '.entitlements'
204-
output_file_path = os.path.join(output_directory, output_file_name)
205-
output_file = open(output_file_path, 'w')
206-
output_file.write(output)
207-
output_file.close()
208-
209-
return output_file_name, cert_authority
210-
211-
21287
def _copy_entitlements_file(
21388
original_entitlements_file_path: str,
21489
output_directory: str,
@@ -261,40 +136,6 @@ def _copy_provisioning_profile(
261136
return dest_provisioning_profile_filename
262137

263138

264-
def _extract_provisioning_profile(
265-
bundle_path: str,
266-
output_directory: str,
267-
unique_id: str) -> Optional[str]:
268-
"""Extracts the profile for the provided bundle to a destination file name.
269-
270-
Given a bundle_path will extract the profile file to the provided
271-
output_directory, and return the filename relative to the output_directory
272-
that the profile has been placed in, or None if no profile exists.
273-
274-
Args:
275-
bundle_path: The absolute path to the bundle to extract profile from.
276-
output_directory: The absolute path to the output directory the profile
277-
should be placed in, it must already exist.
278-
unique_id: Unique identifier to use for filename of extracted profile.
279-
280-
Returns:
281-
The filename relative to output_directory the profile was placed in,
282-
or None if there was no profile found.
283-
"""
284-
embedded_mobileprovision_path = os.path.join(bundle_path,
285-
'embedded.mobileprovision')
286-
embedded_provisioning_profile_path = os.path.join(
287-
bundle_path, 'Contents', 'embedded.provisionprofile')
288-
if os.path.exists(embedded_mobileprovision_path):
289-
original_provisioning_profile_path = embedded_mobileprovision_path
290-
elif os.path.exists(embedded_provisioning_profile_path):
291-
original_provisioning_profile_path = embedded_provisioning_profile_path
292-
else:
293-
return None
294-
return _copy_provisioning_profile(original_provisioning_profile_path,
295-
output_directory, unique_id)
296-
297-
298139
def _generate_manifest(
299140
codesign_identity: Optional[str],
300141
entitlement_file: Optional[str],
@@ -335,115 +176,6 @@ def _generate_manifest(
335176
.EMBEDDED_BUNDLE_MANIFESTS_KEY] = embedded_bundle_manifests
336177
return manifest
337178

338-
339-
def _embedded_manifests_for_path(
340-
bundle_path: str,
341-
dossier_directory: str,
342-
target_directory: str,
343-
codesign_path: str,
344-
) -> List[Dict[str, _ManifestJsonValue]]:
345-
"""Generates embedded manifests for a bundle in a sub-directory.
346-
347-
Provided a bundle, output directory, and a target directory, traverses the
348-
target directory to find any bundles that are signed, and generate manifests.
349-
Copies any referenced assets to the output directory.
350-
351-
Args:
352-
bundle_path: The absolute path to the bundle that will be searched.
353-
dossier_directory: The absolute path to the output dossier directory that
354-
manifest referenced assets will be copied to.
355-
target_directory: The target directory name, relative to the bundle_path, to
356-
be traversed.
357-
codesign_path: Path to the codesign tool as a string.
358-
359-
Returns:
360-
A list of manifest contents with the contents they reference copied into
361-
dossier_directory, or an empty list if no bundles are codesigned.
362-
"""
363-
if target_directory not in _EMBEDDED_BUNDLE_DIRECTORY_NAMES:
364-
raise ValueError(
365-
'Invalid bundle directory for dossier manifest: %s' % target_directory)
366-
367-
embedded_manifests = []
368-
target_directory_path = os.path.join(bundle_path, target_directory)
369-
if os.path.exists(target_directory_path):
370-
target_directory_contents = os.listdir(target_directory_path)
371-
target_directory_contents.sort()
372-
for filename in target_directory_contents:
373-
absolute_embedded_bundle_path = os.path.join(target_directory_path,
374-
filename)
375-
embedded_manifest = _manifest_with_dossier_for_bundle(
376-
absolute_embedded_bundle_path, dossier_directory, codesign_path)
377-
if embedded_manifest is not None:
378-
embedded_manifest[
379-
dossier_reader.EMBEDDED_RELATIVE_PATH_KEY] = os.path.join(
380-
target_directory, filename)
381-
embedded_manifests.append(embedded_manifest)
382-
return embedded_manifests
383-
384-
385-
def _manifest_with_dossier_for_bundle(
386-
bundle_path: str,
387-
dossier_directory: str,
388-
codesign_path: str) -> Optional[Dict[str, _ManifestJsonValue]]:
389-
"""Generates a manifest and assets for a provided bundle.
390-
391-
Provided a bundle and output directory, prepares a code signing dossier by
392-
generating the manifest contents for the bundle referenced and copying any
393-
assets referenced by the manifest into the dossier folder.
394-
395-
Args:
396-
bundle_path: The absolute path to the bundle that a manifest will be
397-
generated for.
398-
dossier_directory: The absolute path to the output dossier directory that
399-
manifest referenced assets will be copied to.
400-
codesign_path: Path to the codesign tool as a string.
401-
402-
Returns:
403-
The manifest contents with files they reference copied into
404-
dossier_directory.
405-
"""
406-
unique_id = str(uuid.uuid4())
407-
entitlements_file, codesign_identity = _extract_codesign_data(
408-
bundle_path, dossier_directory, unique_id, codesign_path)
409-
if not codesign_identity:
410-
return None
411-
provisioning_profile = _extract_provisioning_profile(bundle_path,
412-
dossier_directory,
413-
unique_id)
414-
embedded_manifests = []
415-
for embedded_bundle_directory in _EMBEDDED_BUNDLE_DIRECTORY_NAMES:
416-
embedded_manifests.extend(
417-
_embedded_manifests_for_path(bundle_path, dossier_directory,
418-
embedded_bundle_directory, codesign_path))
419-
if not embedded_manifests:
420-
embedded_manifests = None
421-
return _generate_manifest(codesign_identity, entitlements_file,
422-
provisioning_profile, embedded_manifests)
423-
424-
425-
def _generate_manifest_dossier(parsed_args: argparse.Namespace):
426-
"""Generates a manifest dossier for provided args."""
427-
bundle_path = parsed_args.bundle
428-
dossier_directory = parsed_args.output
429-
430-
packaging_required = False
431-
if parsed_args.zip:
432-
dossier_directory = tempfile.mkdtemp()
433-
packaging_required = True
434-
435-
if not os.path.exists(dossier_directory):
436-
os.makedirs(dossier_directory)
437-
438-
manifest = _manifest_with_dossier_for_bundle(
439-
os.path.abspath(bundle_path), dossier_directory, parsed_args.codesign)
440-
441-
_write_manifest(manifest, dossier_directory)
442-
if packaging_required:
443-
_zip_dossier(dossier_directory, parsed_args.output)
444-
shutil.rmtree(dossier_directory)
445-
446-
447179
def _write_manifest(
448180
manifest: Dict[str, _ManifestJsonValue],
449181
dossier_directory: str) -> None:
@@ -567,40 +299,6 @@ def _create_dossier(parsed_args: argparse.Namespace):
567299
shutil.rmtree(dossier_directory)
568300

569301

570-
def _embed_dossier(parsed_args):
571-
"""Embeds an existing dossier into the specified dossier.
572-
573-
Provided a set of args from generate sub-command, embeds a dossier in a
574-
dossier.
575-
576-
Args:
577-
parsed_args: A struct of arguments required for generating a dossier from a
578-
signed bundle that were generated from an instance of
579-
argparse.ArgumentParser(...).
580-
581-
Raises:
582-
OSError: If any of specified dossiers are not found.
583-
"""
584-
with (dossier_reader.extract_zipped_dossier_if_required(
585-
parsed_args.dossier) as dossier_dir,
586-
dossier_reader.extract_zipped_dossier_if_required(
587-
parsed_args.embedded_dossier_path) as embedded_dossier_dir):
588-
589-
manifest = dossier_reader.read_manifest_from_dossier(dossier_dir.path)
590-
embedded_manifest = dossier_reader.read_manifest_from_dossier(
591-
embedded_dossier_dir.path)
592-
593-
_merge_dossier_contents(embedded_dossier_dir.path, dossier_dir.path)
594-
embedded_manifest[dossier_reader.EMBEDDED_RELATIVE_PATH_KEY] = (
595-
parsed_args.embedded_relative_artifact_path)
596-
manifest[dossier_reader.EMBEDDED_BUNDLE_MANIFESTS_KEY].append(
597-
embedded_manifest)
598-
599-
_write_manifest(manifest, dossier_dir.path)
600-
if dossier_dir.unzipped:
601-
_zip_dossier(dossier_dir.path, parsed_args.dossier)
602-
603-
604302
if __name__ == '__main__':
605303
args = generate_arg_parser().parse_args()
606304
sys.exit(args.func(args))

0 commit comments

Comments
 (0)