Unverified Commit 5d87b3ef authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Migrate code_signing to null safety (#79342)

parent 2cdd5190
...@@ -2,19 +2,16 @@ ...@@ -2,19 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:meta/meta.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
import '../application_package.dart';
import '../base/common.dart'; import '../base/common.dart';
import '../base/config.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/logger.dart'; import '../base/logger.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../build_info.dart'; import '../base/terminal.dart';
import '../convert.dart' show utf8; import '../convert.dart' show utf8;
import '../globals.dart' as globals;
/// User message when no development certificates are found in the keychain. /// User message when no development certificates are found in the keychain.
/// ///
...@@ -95,13 +92,13 @@ final RegExp _certificateOrganizationalUnitExtractionPattern = RegExp(r'OU=([a-z ...@@ -95,13 +92,13 @@ final RegExp _certificateOrganizationalUnitExtractionPattern = RegExp(r'OU=([a-z
/// ///
/// Will return null if none are found, if the user cancels or if the Xcode /// Will return null if none are found, if the user cancels or if the Xcode
/// project has a development team set in the project's build settings. /// project has a development team set in the project's build settings.
Future<Map<String, String>> getCodeSigningIdentityDevelopmentTeam({ Future<Map<String, String>?> getCodeSigningIdentityDevelopmentTeam({
@required BuildableIOSApp iosApp, required Map<String, String>? buildSettings,
@required ProcessManager processManager, required ProcessManager processManager,
@required Logger logger, required Logger logger,
@required BuildInfo buildInfo, required Config config,
required Terminal terminal,
}) async { }) async {
final Map<String, String> buildSettings = await iosApp.project.buildSettingsForBuildInfo(buildInfo);
if (buildSettings == null) { if (buildSettings == null) {
return null; return null;
} }
...@@ -144,16 +141,17 @@ Future<Map<String, String>> getCodeSigningIdentityDevelopmentTeam({ ...@@ -144,16 +141,17 @@ Future<Map<String, String>> getCodeSigningIdentityDevelopmentTeam({
final List<String> validCodeSigningIdentities = findIdentityStdout final List<String> validCodeSigningIdentities = findIdentityStdout
.split('\n') .split('\n')
.map<String>((String outputLine) { .map<String?>((String outputLine) {
return _securityFindIdentityDeveloperIdentityExtractionPattern return _securityFindIdentityDeveloperIdentityExtractionPattern
.firstMatch(outputLine) .firstMatch(outputLine)
?.group(1); ?.group(1);
}) })
.where(_isNotEmpty) .where(_isNotEmpty)
.whereType<String>()
.toSet() // Unique. .toSet() // Unique.
.toList(); .toList();
final String signingIdentity = await _chooseSigningIdentity(validCodeSigningIdentities, logger); final String? signingIdentity = await _chooseSigningIdentity(validCodeSigningIdentities, logger, config, terminal);
// If none are chosen, return null. // If none are chosen, return null.
if (signingIdentity == null) { if (signingIdentity == null) {
...@@ -162,7 +160,7 @@ Future<Map<String, String>> getCodeSigningIdentityDevelopmentTeam({ ...@@ -162,7 +160,7 @@ Future<Map<String, String>> getCodeSigningIdentityDevelopmentTeam({
logger.printStatus('Signing iOS app for device deployment using developer identity: "$signingIdentity"'); logger.printStatus('Signing iOS app for device deployment using developer identity: "$signingIdentity"');
final String signingCertificateId = final String? signingCertificateId =
_securityFindIdentityCertificateCnExtractionPattern _securityFindIdentityCertificateCnExtractionPattern
.firstMatch(signingIdentity) .firstMatch(signingIdentity)
?.group(1); ?.group(1);
...@@ -196,14 +194,24 @@ Future<Map<String, String>> getCodeSigningIdentityDevelopmentTeam({ ...@@ -196,14 +194,24 @@ Future<Map<String, String>> getCodeSigningIdentityDevelopmentTeam({
return null; return null;
} }
return <String, String>{ final String? developmentTeam = _certificateOrganizationalUnitExtractionPattern
'DEVELOPMENT_TEAM': _certificateOrganizationalUnitExtractionPattern
.firstMatch(opensslOutput) .firstMatch(opensslOutput)
?.group(1), ?.group(1);
if (developmentTeam == null) {
return null;
}
return <String, String>{
'DEVELOPMENT_TEAM': developmentTeam,
}; };
} }
Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, Logger logger) async { Future<String?> _chooseSigningIdentity(
List<String> validCodeSigningIdentities,
Logger logger,
Config config,
Terminal terminal,
) async {
// The user has no valid code signing identities. // The user has no valid code signing identities.
if (validCodeSigningIdentities.isEmpty) { if (validCodeSigningIdentities.isEmpty) {
logger.printError(noCertificatesInstruction, emphasis: true); logger.printError(noCertificatesInstruction, emphasis: true);
...@@ -215,7 +223,7 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, L ...@@ -215,7 +223,7 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, L
} }
if (validCodeSigningIdentities.length > 1) { if (validCodeSigningIdentities.length > 1) {
final String savedCertChoice = globals.config.getValue('ios-signing-cert') as String; final String savedCertChoice = config.getValue('ios-signing-cert') as String;
if (savedCertChoice != null) { if (savedCertChoice != null) {
if (validCodeSigningIdentities.contains(savedCertChoice)) { if (validCodeSigningIdentities.contains(savedCertChoice)) {
...@@ -228,7 +236,7 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, L ...@@ -228,7 +236,7 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, L
// If terminal UI can't be used, just attempt with the first valid certificate // If terminal UI can't be used, just attempt with the first valid certificate
// since we can't ask the user. // since we can't ask the user.
if (!globals.terminal.usesTerminalUi) { if (!terminal.usesTerminalUi) {
return validCodeSigningIdentities.first; return validCodeSigningIdentities.first;
} }
...@@ -242,7 +250,7 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, L ...@@ -242,7 +250,7 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, L
} }
logger.printStatus(' a) Abort', emphasis: true); logger.printStatus(' a) Abort', emphasis: true);
final String choice = await globals.terminal.promptForCharInput( final String choice = await terminal.promptForCharInput(
List<String>.generate(count, (int number) => '${number + 1}') List<String>.generate(count, (int number) => '${number + 1}')
..add('a'), ..add('a'),
prompt: 'Please select a certificate for code signing', prompt: 'Please select a certificate for code signing',
...@@ -256,7 +264,7 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, L ...@@ -256,7 +264,7 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, L
} else { } else {
final String selectedCert = validCodeSigningIdentities[int.parse(choice) - 1]; final String selectedCert = validCodeSigningIdentities[int.parse(choice) - 1];
logger.printStatus('Certificate choice "$selectedCert" saved'); logger.printStatus('Certificate choice "$selectedCert" saved');
globals.config.setValue('ios-signing-cert', selectedCert); config.setValue('ios-signing-cert', selectedCert);
return selectedCert; return selectedCert;
} }
} }
...@@ -265,4 +273,4 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, L ...@@ -265,4 +273,4 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, L
} }
/// Returns true if s is a not empty string. /// Returns true if s is a not empty string.
bool _isNotEmpty(String s) => s != null && s.isNotEmpty; bool _isNotEmpty(String? s) => s != null && s.isNotEmpty;
...@@ -177,10 +177,11 @@ Future<XcodeBuildResult> buildXcodeProject({ ...@@ -177,10 +177,11 @@ Future<XcodeBuildResult> buildXcodeProject({
Map<String, String> autoSigningConfigs; Map<String, String> autoSigningConfigs;
if (codesign && buildForDevice) { if (codesign && buildForDevice) {
autoSigningConfigs = await getCodeSigningIdentityDevelopmentTeam( autoSigningConfigs = await getCodeSigningIdentityDevelopmentTeam(
iosApp: app, buildSettings: await app.project.buildSettingsForBuildInfo(buildInfo),
processManager: globals.processManager, processManager: globals.processManager,
logger: globals.logger, logger: globals.logger,
buildInfo: buildInfo, config: globals.config,
terminal: globals.terminal,
); );
} }
......
...@@ -24,7 +24,6 @@ import 'package:mockito/mockito.dart'; ...@@ -24,7 +24,6 @@ import 'package:mockito/mockito.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
import '../../src/fakes.dart'; import '../../src/fakes.dart';
import '../../src/mocks.dart';
final Platform macosPlatform = FakePlatform( final Platform macosPlatform = FakePlatform(
operatingSystem: 'macos', operatingSystem: 'macos',
...@@ -482,13 +481,13 @@ void main() { ...@@ -482,13 +481,13 @@ void main() {
group('log reader', () { group('log reader', () {
FakeProcessManager fakeProcessManager; FakeProcessManager fakeProcessManager;
MockIosProject mockIosProject; FakeIosProject mockIosProject;
MockSimControl mockSimControl; MockSimControl mockSimControl;
Xcode xcode; Xcode xcode;
setUp(() { setUp(() {
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]); fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
mockIosProject = MockIosProject(); mockIosProject = FakeIosProject();
mockSimControl = MockSimControl(); mockSimControl = MockSimControl();
xcode = Xcode.test(processManager: FakeProcessManager.any()); xcode = Xcode.test(processManager: FakeProcessManager.any());
}); });
...@@ -986,3 +985,11 @@ flutter: ...@@ -986,3 +985,11 @@ flutter:
}); });
}); });
} }
class FakeIosProject extends Fake implements IosProject {
@override
Future<String> productBundleIdentifier(BuildInfo buildInfo) async => 'com.example.test';
@override
Future<String> hostAppBundleName(BuildInfo buildInfo) async => 'My Super Awesome App.app';
}
...@@ -174,17 +174,6 @@ Process createMockProcess({ int exitCode = 0, String stdout = '', String stderr ...@@ -174,17 +174,6 @@ Process createMockProcess({ int exitCode = 0, String stdout = '', String stderr
class _MockBasicProcess extends Mock implements Process {} class _MockBasicProcess extends Mock implements Process {}
class MockIosProject extends Mock implements IosProject {
static const String bundleId = 'com.example.test';
static const String appBundleName = 'My Super Awesome App.app';
@override
Future<String> productBundleIdentifier(BuildInfo buildInfo) async => bundleId;
@override
Future<String> hostAppBundleName(BuildInfo buildInfo) async => appBundleName;
}
class MockAndroidDevice extends Mock implements AndroidDevice { class MockAndroidDevice extends Mock implements AndroidDevice {
@override @override
Future<TargetPlatform> get targetPlatform async => TargetPlatform.android_arm; Future<TargetPlatform> get targetPlatform async => TargetPlatform.android_arm;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment