Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intalling certificate for local codesign assets #150

Merged
merged 2 commits into from
Jan 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions autocodesign/autocodesign.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ func (m codesignAssetManager) EnsureCodesignAssets(appLayout AppLayout, opts Cod
devPortalDeviceIDs = append(devPortalDeviceIDs, devPortalDevice.ID)
devPortalDeviceUDIDs = append(devPortalDeviceUDIDs, devPortalDevice.Attributes.UDID)
}

}

codesignAssetsByDistributionType := map[DistributionType]AppCodesignAssets{}
Expand All @@ -191,6 +190,15 @@ func (m codesignAssetManager) EnsureCodesignAssets(appLayout AppLayout, opts Cod
}

printExistingCodesignAssets(localCodesignAssets, distrType)
if localCodesignAssets != nil {
// Did not check if selected certificate is installed yet
fmt.Println()
log.Infof("Installing certificate")
log.Printf("certificate: %s", localCodesignAssets.Certificate.CommonName)
if err := m.assetWriter.InstallCertificate(localCodesignAssets.Certificate); err != nil {
return nil, fmt.Errorf("failed to install certificate: %w", err)
}
}

finalAssets := localCodesignAssets
if missingAppLayout != nil {
Expand All @@ -213,7 +221,7 @@ func (m codesignAssetManager) EnsureCodesignAssets(appLayout AppLayout, opts Cod

// Install new certificates and profiles
fmt.Println()
log.Infof("Install certificates and profiles")
log.Infof("Installing certificates and profiles")
if err := m.assetWriter.Write(map[DistributionType]AppCodesignAssets{distrType: *newCodesignAssets}); err != nil {
return nil, fmt.Errorf("failed to install codesigning files: %w", err)
}
Expand Down
97 changes: 89 additions & 8 deletions autocodesign/autocodesign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ func newMockCertificateProvider(certs []certificateutil.CertificateInfoModel) Ce
func newDefaultMockAssetWriter() AssetWriter {
mockAssetWriter := new(MockAssetWriter)
mockAssetWriter.On("Write", mock.Anything).Return(nil)
mockAssetWriter.On("InstallCertificate", mock.Anything).Return(nil)

return mockAssetWriter
}

func newMockLocalCodeSignAssetManager(assets *AppCodesignAssets, appLayout AppLayout) LocalCodeSignAssetManager {
func newMockLocalCodeSignAssetManager(assets *AppCodesignAssets, missingAppLayout *AppLayout) LocalCodeSignAssetManager {
mockLocalCodeSignAssetManager := new(MockLocalCodeSignAssetManager)
mockLocalCodeSignAssetManager.On("FindCodesignAssets", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(assets, &appLayout, nil)
mockLocalCodeSignAssetManager.On("FindCodesignAssets", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(assets, missingAppLayout, nil)

return mockLocalCodeSignAssetManager
}
Expand Down Expand Up @@ -211,7 +212,7 @@ func Test_codesignAssetManager_EnsureCodesignAssets(t *testing.T) {
devPortalClient: checkOnlyDevportalProfile,
certificateProvider: newMockCertificateProvider([]certificateutil.CertificateInfoModel{devCert}),
assetWriter: newDefaultMockAssetWriter(),
localCodeSignAssetManager: newMockLocalCodeSignAssetManager(nil, appIDAndProfileFoundAppLayout),
localCodeSignAssetManager: newMockLocalCodeSignAssetManager(nil, &appIDAndProfileFoundAppLayout),
},
appLayout: appIDAndProfileFoundAppLayout,
opts: CodesignAssetsOpts{
Expand All @@ -234,7 +235,7 @@ func Test_codesignAssetManager_EnsureCodesignAssets(t *testing.T) {
devPortalClient: checkOnlyDevportalProfile,
certificateProvider: newMockCertificateProvider([]certificateutil.CertificateInfoModel{devCert}),
assetWriter: newDefaultMockAssetWriter(),
localCodeSignAssetManager: newMockLocalCodeSignAssetManager(&localCodeSignAsset, appIDAndProfileFoundAppLayout),
localCodeSignAssetManager: newMockLocalCodeSignAssetManager(&localCodeSignAsset, &appIDAndProfileFoundAppLayout),
},
appLayout: appIDAndProfileFoundAppLayout2,
opts: CodesignAssetsOpts{
Expand All @@ -257,7 +258,7 @@ func Test_codesignAssetManager_EnsureCodesignAssets(t *testing.T) {
fields: fields{
devPortalClient: devportalWithNoAppID,
certificateProvider: newMockCertificateProvider([]certificateutil.CertificateInfoModel{devCert}),
localCodeSignAssetManager: newMockLocalCodeSignAssetManager(nil, icloudContainerAppLayout),
localCodeSignAssetManager: newMockLocalCodeSignAssetManager(nil, &icloudContainerAppLayout),
},
appLayout: icloudContainerAppLayout,
opts: CodesignAssetsOpts{
Expand Down Expand Up @@ -304,7 +305,7 @@ func Test_GivenNoValidAppID_WhenEnsureAppClipProfile_ThenItFails(t *testing.T) {
},
}

localCodeSignAssetManager := newMockLocalCodeSignAssetManager(nil, appLayout)
localCodeSignAssetManager := newMockLocalCodeSignAssetManager(nil, &appLayout)
manager := NewCodesignAssetManager(client, certProvider, assetWriter, localCodeSignAssetManager)

opts := CodesignAssetsOpts{
Expand Down Expand Up @@ -340,7 +341,7 @@ func Test_GivenAppIDWithoutAppleSignIn_WhenEnsureAppClipProfile_ThenItFails(t *t
},
}

localCodeSignAssetManager := newMockLocalCodeSignAssetManager(nil, appLayout)
localCodeSignAssetManager := newMockLocalCodeSignAssetManager(nil, &appLayout)
manager := NewCodesignAssetManager(client, certProvider, assetWriter, localCodeSignAssetManager)

opts := CodesignAssetsOpts{
Expand Down Expand Up @@ -412,7 +413,7 @@ func Test_GivenProfileExpired_WhenProfilesInconsistent_ThenItRetries(t *testing.
},
}

localCodeSignAssetManager := newMockLocalCodeSignAssetManager(nil, appLayout)
localCodeSignAssetManager := newMockLocalCodeSignAssetManager(nil, &appLayout)
manager := NewCodesignAssetManager(client, certProvider, assetWriter, localCodeSignAssetManager)

opts := CodesignAssetsOpts{
Expand All @@ -426,6 +427,86 @@ func Test_GivenProfileExpired_WhenProfilesInconsistent_ThenItRetries(t *testing.
require.NoError(t, err)
}

func Test_GivenLocalProfile_WhenCertificateIsMissing_ThenInstalled(t *testing.T) {
// Given
const teamID = "MY_TEAM_ID"
expiry := time.Now().AddDate(1, 0, 0)
devCert1 := newCertificate(t, teamID, "MY_TEAM", "Apple Development: test 1", expiry)
devCert2 := newCertificate(t, teamID, "MY_TEAM", "Apple Development: test 2", expiry)

validProfile := newMockProfile(profileArgs{
attributes: appstoreconnect.ProfileAttributes{
Name: profileName(appstoreconnect.IOSAppDevelopment, "io.test"),
ProfileState: appstoreconnect.Active,
ExpirationDate: appstoreconnect.Time(expiry),
},
certificates: []string{"dev1", "dev2"},
})

client := newMockDevportalClient(devportalArgs{
certs: map[appstoreconnect.CertificateType][]Certificate{
appstoreconnect.IOSDevelopment: {
{
CertificateInfo: devCert1,
ID: "dev1",
},
{
CertificateInfo: devCert2,
ID: "dev2",
},
},
},
profiles: map[appstoreconnect.ProfileType][]Profile{
appstoreconnect.IOSAppDevelopment: {validProfile},
},
appIDs: []appstoreconnect.BundleID{{
Attributes: appstoreconnect.BundleIDAttributes{
Identifier: "io.test",
Name: "test-app",
},
}},
})

assetWriter := new(MockAssetWriter)
assetWriter.On("Write", mock.Anything).Return(nil)
assetWriter.On("InstallCertificate", devCert2).Return(nil).Once()
appLayout := AppLayout{
Platform: IOS,
EntitlementsByArchivableTargetBundleID: map[string]Entitlements{
"io.test": {},
},
}

certProvider := newMockCertificateProvider([]certificateutil.CertificateInfoModel{devCert1})
localCodeSignAssetManager := newMockLocalCodeSignAssetManager(&AppCodesignAssets{
ArchivableTargetProfilesByBundleID: map[string]Profile{
"io.test": validProfile,
},
Certificate: devCert2,
}, nil)
manager := NewCodesignAssetManager(client, certProvider, assetWriter, localCodeSignAssetManager)

opts := CodesignAssetsOpts{
DistributionType: Development,
}

wantAssets := map[DistributionType]AppCodesignAssets{
Development: {
ArchivableTargetProfilesByBundleID: map[string]Profile{
"io.test": validProfile,
},
Certificate: devCert2,
},
}

// When
gotAssets, err := manager.EnsureCodesignAssets(appLayout, opts)

// Then
require.NoError(t, err)
require.Equal(t, wantAssets, gotAssets)
}

func newClientWithoutAppIDAndProfile(cert certificateutil.CertificateInfoModel) *MockDevPortalClient {
client := newMockDevportalClient(devportalArgs{
certs: map[appstoreconnect.CertificateType][]Certificate{
Expand Down