feat: share env files as encrypted links #54
No files matched your search
@@ -134,13 +134,14 @@ func (p *Provider) Value(ctx context.Context, o provider.Object) (provider.Secre
|
|||||||
return provider.NewSecretValue([]byte(v)), nil
|
return provider.NewSecretValue([]byte(v)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Locate finds the source holding the vault (by host) or the workspace.
|
// Locate finds the source holding the vault (by host), the workspace or
|
||||||
|
// the repo (by its remote).
|
||||||
func (p *Provider) Locate(ctx context.Context, host string) (string, bool, error) {
|
func (p *Provider) Locate(ctx context.Context, host string) (string, bool, error) {
|
||||||
if err := p.wait(ctx); err != nil {
|
if err := p.wait(ctx); err != nil {
|
||||||
return "", false, err
|
return "", false, err
|
||||||
}
|
}
|
||||||
for _, src := range p.sources {
|
for _, src := range p.sources {
|
||||||
if p.kind == provider.KindDatabricks && src.Detail == host {
|
if (p.kind == provider.KindDatabricks || p.kind == provider.KindRepo) && strings.EqualFold(src.Detail, host) {
|
||||||
return src.ID, true, nil
|
return src.ID, true, nil
|
||||||
}
|
}
|
||||||
for _, c := range p.containers[src.ID] {
|
for _, c := range p.containers[src.ID] {
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ func Repos() *Provider {
|
|||||||
"database.url", "postgres://app:stg-Pg-2b8d1L@pg-demo-stg:5432/app",
|
"database.url", "postgres://app:stg-Pg-2b8d1L@pg-demo-stg:5432/app",
|
||||||
"stripe.secret_key", "sk_test_demo_51NxDemoKey0000")
|
"stripe.secret_key", "sk_test_demo_51NxDemoKey0000")
|
||||||
file(api, "config/oauth.enc.json", "age", "tracked", "e03b6f1 · 2 months ago",
|
file(api, "config/oauth.enc.json", "age", "tracked", "e03b6f1 · 2 months ago",
|
||||||
"github.client_secret", "ghs_demo0000000000000000000000",
|
"github.client_secret", "8f3c2a9d7e1b6f4a0c5d2e9b8a7f6c3d1e0b4a5f",
|
||||||
"google.client_secret", "GOCSPX-demo-000000000000")
|
"google.client_secret", "GOCSPX-demo-000000000000")
|
||||||
file(api, ".env", "", "ignored", "",
|
file(api, ".env", "", "ignored", "",
|
||||||
"DATABASE_URL", "postgres://app:local@localhost:5432/app",
|
"DATABASE_URL", "postgres://app:local@localhost:5432/app",
|
||||||
|
|||||||
@@ -251,7 +251,8 @@ func (m *Model) openShare(s share.Sealed) tea.Cmd {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
for _, p := range providers {
|
for _, p := range providers {
|
||||||
if loc, ok := p.(provider.Locator); ok && p.Kind() == provider.KindRepo && s.Repo != "" {
|
if loc, ok := p.(provider.Locator); ok && p.Kind() == provider.KindRepo && s.Repo != "" {
|
||||||
if root, found, _ := loc.Locate(ctx, s.Repo); found {
|
// Its clone, if it's on disk (the demo's aren't).
|
||||||
|
if root, found, _ := loc.Locate(ctx, s.Repo); found && isDir(root) {
|
||||||
msg.dir = root
|
msg.dir = root
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -354,6 +355,12 @@ func (m *Model) offerWrite(files []share.File, dir string) {
|
|||||||
m.showMenu("Save the shared files", lines, opts)
|
m.showMenu("Save the shared files", lines, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isDir reports whether dir is a folder on disk.
|
||||||
|
func isDir(dir string) bool {
|
||||||
|
info, err := os.Stat(dir)
|
||||||
|
return err == nil && info.IsDir()
|
||||||
|
}
|
||||||
|
|
||||||
// expandHome expands a leading ~/ to the home folder.
|
// expandHome expands a leading ~/ to the home folder.
|
||||||
func expandHome(dir string) string {
|
func expandHome(dir string) string {
|
||||||
if rest, ok := strings.CutPrefix(dir, "~/"); ok {
|
if rest, ok := strings.CutPrefix(dir, "~/"); ok {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -203,10 +204,19 @@ func TestShareInDemo(t *testing.T) {
|
|||||||
if !strings.HasPrefix(clip.content, "lazysecrets://share/") {
|
if !strings.HasPrefix(clip.content, "lazysecrets://share/") {
|
||||||
t.Fatalf("copied %q (%s)", clip.content, d.m.flash.text)
|
t.Fatalf("copied %q (%s)", clip.content, d.m.flash.text)
|
||||||
}
|
}
|
||||||
|
link := clip.content
|
||||||
|
// A value in a demo repo's SOPS file can be the key too, found by
|
||||||
|
// the repo's remote.
|
||||||
|
clip.content = ""
|
||||||
|
d.run(d.m.shareFiles(src, nil))
|
||||||
|
d.send(tea.PasteMsg{Content: "lazysecrets://repo/" + url.PathEscape(src.Detail) + "/config%2Foauth.enc.json/github.client_secret"})
|
||||||
|
if !strings.HasPrefix(clip.content, "lazysecrets://share/") {
|
||||||
|
t.Errorf("with the demo repo's key: copied %q (%s)", clip.content, d.m.flash.text)
|
||||||
|
}
|
||||||
|
|
||||||
dir, _ := filepath.EvalSymlinks(t.TempDir())
|
dir, _ := filepath.EvalSymlinks(t.TempDir())
|
||||||
d.m.placeDir = dir
|
d.m.placeDir = dir
|
||||||
d.send(tea.PasteMsg{Content: clip.content})
|
d.send(tea.PasteMsg{Content: link})
|
||||||
d.keys("o")
|
d.keys("o")
|
||||||
if d.m.prompt == nil || d.m.prompt.input == nil || !strings.Contains(d.screen(), "isn't among your repos") {
|
if d.m.prompt == nil || d.m.prompt.input == nil || !strings.Contains(d.screen(), "isn't among your repos") {
|
||||||
t.Fatalf("doesn't ask where:\n%s", d.screen())
|
t.Fatalf("doesn't ask where:\n%s", d.screen())
|
||||||
|
|||||||
Reference in new issue
Block a user