From caa06d7eeadb7724fab4f1c994f3b87d5ecbcbe8 Mon Sep 17 00:00:00 2001 From: Viktor Benei Date: Tue, 6 Dec 2016 13:17:47 +0100 Subject: [PATCH 1/2] TeamID handling revision Instead of reading it from `Entitlements` (`com.apple.developer.team-identifier`), read it from the main `TeamIdentifier` array Why: we received a report where a provisioning profile had an array defined for `com.apple.developer.team-identifier` instead of a string. --- cmd/common.go | 16 +++- provprofile/provprofile.go | 44 ++++++++--- provprofile/provprofile_test.go | 129 ++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+), 13 deletions(-) diff --git a/cmd/common.go b/cmd/common.go index 79000475..076802d4 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -140,7 +140,12 @@ func exportCodeSigningFiles(toolName, absExportOutputDirPath string, codeSigning return printFinishedWithError(toolName, "Failed to export Provisioning Profiles, error: %s", err) } - if err := collectAndExportIdentities(codeSigningSettings, exportedProvProfiles.CollectTeamIDs(), absExportOutputDirPath); err != nil { + teamIDs, err := exportedProvProfiles.CollectTeamIDs() + if err != nil { + return printFinishedWithError(toolName, "Failed to collect Team IDs from Provisioning Profiles, error: %s", err) + } + + if err := collectAndExportIdentities(codeSigningSettings, teamIDs, absExportOutputDirPath); err != nil { return printFinishedWithError(toolName, "Failed to export identities, error: %s", err) } @@ -306,13 +311,20 @@ func exportProvisioningProfiles(provProfileFileInfos []provprofile.ProvisioningP fmt.Println() } provProfileInfo := aProvProfileFileInfo.ProvisioningProfileInfo + teamID, err := provProfileInfo.TeamID() + if err != nil { + return fmt.Errorf("Invalid Team ID in provisioning profile (uuid: %s), error: %s", + provProfileInfo.UUID, err) + } + log.Infoln(" "+colorstring.Green("Exporting Provisioning Profile:"), provProfileInfo.Name) log.Infoln(" App ID Name:", provProfileInfo.AppIDName) log.Infoln(" App ID:", provProfileInfo.Entitlements.AppID) log.Infoln(" Expiration Date:", provProfileInfo.ExpirationDate) log.Infoln(" UUID:", provProfileInfo.UUID) log.Infoln(" TeamName:", provProfileInfo.TeamName) - log.Infoln(" Team ID:", provProfileInfo.Entitlements.TeamID) + log.Infoln(" Team ID:", teamID) + exportFileName := provProfileExportFileName(aProvProfileFileInfo) exportPth := filepath.Join(exportTargetDirPath, exportFileName) if err := cmdex.RunCommand("cp", aProvProfileFileInfo.Path, exportPth); err != nil { diff --git a/provprofile/provprofile.go b/provprofile/provprofile.go index 037b6f0c..915f0994 100644 --- a/provprofile/provprofile.go +++ b/provprofile/provprofile.go @@ -1,6 +1,7 @@ package provprofile import ( + "errors" "fmt" "path/filepath" "strings" @@ -26,18 +27,35 @@ type ProvisioningProfileInfo struct { // EntitlementsModel ... type EntitlementsModel struct { - AppID string `plist:"application-identifier"` - TeamID string `plist:"com.apple.developer.team-identifier"` + AppID string `plist:"application-identifier"` } // ProvisioningProfileModel ... type ProvisioningProfileModel struct { - Entitlements EntitlementsModel `plist:"Entitlements"` - UUID string `plist:"UUID"` - TeamName string `plist:"TeamName"` - Name string `plist:"Name"` - AppIDName string `plist:"AppIDName"` - ExpirationDate time.Time `plist:"ExpirationDate"` + Entitlements EntitlementsModel `plist:"Entitlements"` + UUID string `plist:"UUID"` + TeamName string `plist:"TeamName"` + Name string `plist:"Name"` + AppIDName string `plist:"AppIDName"` + TeamIdentifiers []string `plist:"TeamIdentifier"` + ExpirationDate time.Time `plist:"ExpirationDate"` +} + +// TeamID ... +func (provProfile ProvisioningProfileModel) TeamID() (string, error) { + if len(provProfile.TeamIdentifiers) == 0 { + return "", errors.New("No TeamIdentifier specified") + } + if len(provProfile.TeamIdentifiers) != 1 { + return "", errors.New("More than one TeamIdentifier specified") + } + + teamID := provProfile.TeamIdentifiers[0] + if len(teamID) == 0 { + return "", errors.New("An empty item specified for TeamIdentifier") + } + + return teamID, nil } // ProvisioningProfileFileInfoModel ... @@ -50,12 +68,16 @@ type ProvisioningProfileFileInfoModel struct { type ProvisioningProfileFileInfoModels []ProvisioningProfileFileInfoModel // CollectTeamIDs ... -func (ppFileInfos ProvisioningProfileFileInfoModels) CollectTeamIDs() []string { +func (ppFileInfos ProvisioningProfileFileInfoModels) CollectTeamIDs() ([]string, error) { teamIDsMap := map[string]interface{}{} for _, aProvProfileFileInfo := range ppFileInfos { - teamIDsMap[aProvProfileFileInfo.ProvisioningProfileInfo.Entitlements.TeamID] = 1 + teamID, err := aProvProfileFileInfo.ProvisioningProfileInfo.TeamID() + if err != nil { + return []string{}, fmt.Errorf("Team ID error for profile (uuid: %s), error: %s", aProvProfileFileInfo.ProvisioningProfileInfo.UUID, err) + } + teamIDsMap[teamID] = 1 } - return maputil.KeysOfStringInterfaceMap(teamIDsMap) + return maputil.KeysOfStringInterfaceMap(teamIDsMap), nil } // CreateProvisioningProfileModelFromFile ... diff --git a/provprofile/provprofile_test.go b/provprofile/provprofile_test.go index 5ea90635..51e8bc4c 100644 --- a/provprofile/provprofile_test.go +++ b/provprofile/provprofile_test.go @@ -1 +1,130 @@ package provprofile + +import "testing" +import "github.com/stretchr/testify/require" +import "github.com/bitrise-io/go-utils/testutil" + +func Test_ProvisioningProfileModel_TeamID(t *testing.T) { + t.Log("Empty TeamIdentifiers") + { + provProfile := ProvisioningProfileModel{} + teamID, err := provProfile.TeamID() + require.EqualError(t, err, "No TeamIdentifier specified") + require.Equal(t, "", teamID) + } + + t.Log("One TeamIdentifier - valid") + { + provProfile := ProvisioningProfileModel{ + TeamIdentifiers: []string{"TeamID1"}, + } + teamID, err := provProfile.TeamID() + require.NoError(t, err) + require.Equal(t, "TeamID1", teamID) + } + + t.Log("One empty TeamIdentifier - invalid") + { + provProfile := ProvisioningProfileModel{ + TeamIdentifiers: []string{""}, + } + teamID, err := provProfile.TeamID() + require.EqualError(t, err, "An empty item specified for TeamIdentifier") + require.Equal(t, "", teamID) + } + + t.Log("Two TeamIdentifiers") + { + provProfile := ProvisioningProfileModel{ + TeamIdentifiers: []string{ + "TeamID1", "TeamID2", + }, + } + teamID, err := provProfile.TeamID() + require.EqualError(t, err, "More than one TeamIdentifier specified") + require.Equal(t, "", teamID) + } +} + +func Test_ProvisioningProfileFileInfoModels_CollectTeamIDs(t *testing.T) { + t.Log("Empty") + { + ppFileInfos := ProvisioningProfileFileInfoModels{} + teamIDs, err := ppFileInfos.CollectTeamIDs() + require.NoError(t, err) + require.Equal(t, []string{}, teamIDs) + } + + t.Log("One item") + { + ppFileInfos := ProvisioningProfileFileInfoModels{ + ProvisioningProfileFileInfoModel{ + ProvisioningProfileInfo: ProvisioningProfileModel{ + TeamIdentifiers: []string{"TeamID1"}, + }, + }, + } + teamIDs, err := ppFileInfos.CollectTeamIDs() + require.NoError(t, err) + require.Equal(t, []string{"TeamID1"}, teamIDs) + } + + t.Log("Two distinct items with different team IDs") + { + ppFileInfos := ProvisioningProfileFileInfoModels{ + { + ProvisioningProfileInfo: ProvisioningProfileModel{ + TeamIdentifiers: []string{"TeamID1"}, + }, + }, + { + ProvisioningProfileInfo: ProvisioningProfileModel{ + TeamIdentifiers: []string{"TeamID2"}, + }, + }, + } + teamIDs, err := ppFileInfos.CollectTeamIDs() + require.NoError(t, err) + testutil.EqualSlicesWithoutOrder(t, []string{"TeamID1", "TeamID2"}, teamIDs) + } + + t.Log("Two distinct items with same team IDs") + { + ppFileInfos := ProvisioningProfileFileInfoModels{ + { + ProvisioningProfileInfo: ProvisioningProfileModel{ + TeamIdentifiers: []string{"TeamID1"}, + }, + }, + { + ProvisioningProfileInfo: ProvisioningProfileModel{ + TeamIdentifiers: []string{"TeamID1"}, + }, + }, + } + teamIDs, err := ppFileInfos.CollectTeamIDs() + require.NoError(t, err) + require.Equal(t, []string{"TeamID1"}, teamIDs) + } + + t.Log("Two items, the second one's TeamID is invalid") + { + ppFileInfos := ProvisioningProfileFileInfoModels{ + { + ProvisioningProfileInfo: ProvisioningProfileModel{ + UUID: "UUID1", + TeamIdentifiers: []string{"TeamID1"}, + }, + }, + { + ProvisioningProfileInfo: ProvisioningProfileModel{ + UUID: "UUID2", + TeamIdentifiers: []string{""}, + }, + }, + } + teamIDs, err := ppFileInfos.CollectTeamIDs() + require.EqualError(t, err, "Team ID error for profile (uuid: UUID2), error: An empty item specified for TeamIdentifier") + require.Equal(t, []string{}, teamIDs) + } +} From 23f6ba40f1fb14a95fe898d99cb966287b4fc961 Mon Sep 17 00:00:00 2001 From: Viktor Benei Date: Tue, 6 Dec 2016 13:22:17 +0100 Subject: [PATCH 2/2] variable name revision --- cmd/common.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/common.go b/cmd/common.go index 076802d4..c04c2940 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -140,12 +140,12 @@ func exportCodeSigningFiles(toolName, absExportOutputDirPath string, codeSigning return printFinishedWithError(toolName, "Failed to export Provisioning Profiles, error: %s", err) } - teamIDs, err := exportedProvProfiles.CollectTeamIDs() + provProfileTeamIDs, err := exportedProvProfiles.CollectTeamIDs() if err != nil { return printFinishedWithError(toolName, "Failed to collect Team IDs from Provisioning Profiles, error: %s", err) } - if err := collectAndExportIdentities(codeSigningSettings, teamIDs, absExportOutputDirPath); err != nil { + if err := collectAndExportIdentities(codeSigningSettings, provProfileTeamIDs, absExportOutputDirPath); err != nil { return printFinishedWithError(toolName, "Failed to export identities, error: %s", err) } @@ -311,7 +311,7 @@ func exportProvisioningProfiles(provProfileFileInfos []provprofile.ProvisioningP fmt.Println() } provProfileInfo := aProvProfileFileInfo.ProvisioningProfileInfo - teamID, err := provProfileInfo.TeamID() + provProfileTeamID, err := provProfileInfo.TeamID() if err != nil { return fmt.Errorf("Invalid Team ID in provisioning profile (uuid: %s), error: %s", provProfileInfo.UUID, err) @@ -323,7 +323,7 @@ func exportProvisioningProfiles(provProfileFileInfos []provprofile.ProvisioningP log.Infoln(" Expiration Date:", provProfileInfo.ExpirationDate) log.Infoln(" UUID:", provProfileInfo.UUID) log.Infoln(" TeamName:", provProfileInfo.TeamName) - log.Infoln(" Team ID:", teamID) + log.Infoln(" Team ID:", provProfileTeamID) exportFileName := provProfileExportFileName(aProvProfileFileInfo) exportPth := filepath.Join(exportTargetDirPath, exportFileName)