Skip to content

Commit e1afe7f

Browse files
committed
chore: begin work implementing vsix signatures, manifest matching
1 parent 3e808a6 commit e1afe7f

File tree

6 files changed

+60
-11
lines changed

6 files changed

+60
-11
lines changed

cli/add.go

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
67
"os"
78
"path/filepath"
@@ -12,6 +13,7 @@ import (
1213

1314
"cdr.dev/slog"
1415
"cdr.dev/slog/sloggers/sloghuman"
16+
"github.com/coder/code-marketplace/internal/extensionsign"
1517

1618
"github.com/coder/code-marketplace/storage"
1719
"github.com/coder/code-marketplace/util"
@@ -22,6 +24,7 @@ func add() *cobra.Command {
2224
artifactory string
2325
extdir string
2426
repo string
27+
signature bool
2528
)
2629

2730
cmd := &cobra.Command{
@@ -73,7 +76,7 @@ func add() *cobra.Command {
7376
return err
7477
}
7578
for _, file := range files {
76-
s, err := doAdd(ctx, filepath.Join(args[0], file.Name()), store)
79+
s, err := doAdd(ctx, filepath.Join(args[0], file.Name()), signature, store)
7780
if err != nil {
7881
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Failed to unpack %s: %s\n", file.Name(), err.Error())
7982
failed = append(failed, file.Name())
@@ -82,7 +85,7 @@ func add() *cobra.Command {
8285
}
8386
}
8487
} else {
85-
s, err := doAdd(ctx, args[0], store)
88+
s, err := doAdd(ctx, args[0], signature, store)
8689
if err != nil {
8790
return err
8891
}
@@ -102,11 +105,12 @@ func add() *cobra.Command {
102105
cmd.Flags().StringVar(&extdir, "extensions-dir", "", "The path to extensions.")
103106
cmd.Flags().StringVar(&artifactory, "artifactory", "", "Artifactory server URL.")
104107
cmd.Flags().StringVar(&repo, "repo", "", "Artifactory repository.")
108+
cmd.Flags().BoolVar(&signature, "signature", true, "Include signature")
105109

106110
return cmd
107111
}
108112

109-
func doAdd(ctx context.Context, source string, store storage.Storage) ([]string, error) {
113+
func doAdd(ctx context.Context, source string, includeSignature bool, store storage.Storage) ([]string, error) {
110114
// Read in the extension. In the future we might support stdin as well.
111115
vsix, err := storage.ReadVSIX(ctx, source)
112116
if err != nil {
@@ -120,7 +124,31 @@ func doAdd(ctx context.Context, source string, store storage.Storage) ([]string,
120124
return nil, err
121125
}
122126

123-
location, err := store.AddExtension(ctx, manifest, vsix)
127+
var extra []storage.File
128+
if includeSignature {
129+
sigManifest, err := extensionsign.GenerateSignatureManifest(vsix)
130+
if err != nil {
131+
return nil, xerrors.Errorf("generate signature manifest: %w", err)
132+
}
133+
134+
data, err := json.Marshal(sigManifest)
135+
if err != nil {
136+
return nil, xerrors.Errorf("marshal signature manifest: %w", err)
137+
}
138+
139+
extra = append(extra, storage.File{
140+
RelativePath: "extension.sigzip",
141+
Content: data,
142+
})
143+
144+
manifest.Assets.Asset = append(manifest.Assets.Asset, storage.VSIXAsset{
145+
Type: storage.VSIXSignatureType,
146+
Path: "extension.sigzip",
147+
Addressable: "true", // TODO: Idk if this is right
148+
})
149+
}
150+
151+
location, err := store.AddExtension(ctx, manifest, vsix, extra...)
124152
if err != nil {
125153
return nil, err
126154
}

cli/root.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package cli
22

33
import (
4-
"github.com/spf13/cobra"
54
"strings"
5+
6+
"github.com/spf13/cobra"
67
)
78

89
func Root() *cobra.Command {
@@ -16,7 +17,7 @@ func Root() *cobra.Command {
1617
}, "\n"),
1718
}
1819

19-
cmd.AddCommand(add(), remove(), server(), version())
20+
cmd.AddCommand(add(), remove(), server(), version(), signature())
2021

2122
cmd.PersistentFlags().BoolP("verbose", "v", false, "Enable verbose output")
2223

storage/artifactory.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ func (s *Artifactory) upload(ctx context.Context, endpoint string, r io.Reader)
213213
return code, nil
214214
}
215215

216-
func (s *Artifactory) AddExtension(ctx context.Context, manifest *VSIXManifest, vsix []byte) (string, error) {
216+
func (s *Artifactory) AddExtension(ctx context.Context, manifest *VSIXManifest, vsix []byte, extra ...File) (string, error) {
217217
// Extract the zip to the correct path.
218218
identity := manifest.Metadata.Identity
219219
dir := path.Join(identity.Publisher, identity.ID, Version{

storage/local.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"sync"
1212
"time"
1313

14+
"golang.org/x/xerrors"
15+
1416
"cdr.dev/slog"
1517
)
1618

@@ -89,7 +91,7 @@ func (s *Local) list(ctx context.Context) []extension {
8991
return list
9092
}
9193

92-
func (s *Local) AddExtension(ctx context.Context, manifest *VSIXManifest, vsix []byte) (string, error) {
94+
func (s *Local) AddExtension(ctx context.Context, manifest *VSIXManifest, vsix []byte, extra ...File) (string, error) {
9395
// Extract the zip to the correct path.
9496
identity := manifest.Metadata.Identity
9597
dir := filepath.Join(s.extdir, identity.Publisher, identity.ID, Version{
@@ -121,6 +123,18 @@ func (s *Local) AddExtension(ctx context.Context, manifest *VSIXManifest, vsix [
121123
return "", err
122124
}
123125

126+
for _, file := range extra {
127+
path := filepath.Join(dir, file.RelativePath)
128+
err := os.MkdirAll(filepath.Dir(path), 0o644)
129+
if err != nil {
130+
return "", err
131+
}
132+
err = os.WriteFile(path, file.Content, 0o644)
133+
if err != nil {
134+
return dir, xerrors.Errorf("write extra file %q: %w", path, err)
135+
}
136+
}
137+
124138
return dir, nil
125139
}
126140

storage/storage.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ type AssetType string
112112
const (
113113
ManifestAssetType AssetType = "Microsoft.VisualStudio.Code.Manifest" // This is the package.json.
114114
VSIXAssetType AssetType = "Microsoft.VisualStudio.Services.VSIXPackage"
115+
VSIXSignatureType AssetType = "Microsoft.VisualStudio.Services.VsixSignature"
115116
)
116117

117118
// VSIXAsset implements XMLManifest.PackageManifest.Assets.Asset.
@@ -203,8 +204,8 @@ func (vs ByVersion) Less(i, j int) bool {
203204

204205
type Storage interface {
205206
// AddExtension adds the provided VSIX into storage and returns the location
206-
// for verification purposes.
207-
AddExtension(ctx context.Context, manifest *VSIXManifest, vsix []byte) (string, error)
207+
// for verification purposes. Extra files can be included, but not required.
208+
AddExtension(ctx context.Context, manifest *VSIXManifest, vsix []byte, extra ...File) (string, error)
208209
// FileServer provides a handler for fetching extension repository files from
209210
// a client.
210211
FileServer() http.Handler
@@ -230,6 +231,11 @@ type Storage interface {
230231
WalkExtensions(ctx context.Context, fn func(manifest *VSIXManifest, versions []Version) error) error
231232
}
232233

234+
type File struct {
235+
RelativePath string
236+
Content []byte
237+
}
238+
233239
const ArtifactoryTokenEnvKey = "ARTIFACTORY_TOKEN"
234240

235241
// NewStorage returns a storage instance based on the provided extension

testutil/mockstorage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func NewMockStorage() *MockStorage {
1717
return &MockStorage{}
1818
}
1919

20-
func (s *MockStorage) AddExtension(ctx context.Context, manifest *storage.VSIXManifest, vsix []byte) (string, error) {
20+
func (s *MockStorage) AddExtension(ctx context.Context, manifest *storage.VSIXManifest, vsix []byte, extra ...storage.File) (string, error) {
2121
return "", errors.New("not implemented")
2222
}
2323

0 commit comments

Comments
 (0)