package browserbridge import ( "context" "fmt" "net" "strings" "git.julianfamily.org/keepassgo/internal/grpcaddr" keepassgov1 "git.julianfamily.org/keepassgo/proto/keepassgo/v1" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" ) type GRPCClient struct { client keepassgov1.VaultServiceClient } func DialRequest(ctx context.Context, req Request, grpcAddr string) (*grpc.ClientConn, *GRPCClient, context.Context, error) { conn, err := req.Connection(grpcAddr) if err != nil { return nil, nil, nil, err } return Dial(ctx, conn) } func Dial(ctx context.Context, conn Connection) (*grpc.ClientConn, *GRPCClient, context.Context, error) { normalized, err := normalizeConnection(conn) if err != nil { return nil, nil, nil, err } network, endpoint, err := grpcaddr.Parse(normalized.GRPCAddress) if err != nil { return nil, nil, nil, err } target := endpoint if network == "unix" { target = "passthrough:///" + endpoint } grpcConn, err := grpc.NewClient(target, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { return net.Dial(network, endpoint) }), ) if err != nil { return nil, nil, nil, fmt.Errorf("dial gRPC host %s: %w", normalized.GRPCAddress, err) } ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer "+normalized.BearerToken) return grpcConn, &GRPCClient{client: keepassgov1.NewVaultServiceClient(grpcConn)}, ctx, nil } func (c *GRPCClient) Status(ctx context.Context) (*keepassgov1.GetSessionStatusResponse, error) { return c.client.GetSessionStatus(ctx, &keepassgov1.GetSessionStatusRequest{}) } func (c *GRPCClient) FindBrowserLogins(ctx context.Context, pageURL string) ([]*keepassgov1.BrowserLoginMatch, error) { resp, err := c.client.FindBrowserLogins(ctx, &keepassgov1.FindBrowserLoginsRequest{ PageUrl: strings.TrimSpace(pageURL), }) if err != nil { return nil, err } return resp.GetMatches(), nil } func (c *GRPCClient) ListEntries(ctx context.Context, path []string, query string) ([]*keepassgov1.Entry, error) { resp, err := c.client.ListEntries(ctx, &keepassgov1.ListEntriesRequest{ Path: append([]string(nil), path...), Query: strings.TrimSpace(query), }) if err != nil { return nil, err } return resp.GetEntries(), nil } func (c *GRPCClient) GetBrowserCredential(ctx context.Context, entryID, pageURL string) (*keepassgov1.GetBrowserCredentialResponse, error) { return c.client.GetBrowserCredential(ctx, &keepassgov1.GetBrowserCredentialRequest{ Id: strings.TrimSpace(entryID), PageUrl: strings.TrimSpace(pageURL), }) } func (c *GRPCClient) UpsertEntry(ctx context.Context, entry *keepassgov1.Entry) (*keepassgov1.Entry, error) { resp, err := c.client.UpsertEntry(ctx, &keepassgov1.UpsertEntryRequest{Entry: entry}) if err != nil { return nil, err } return resp.GetEntry(), nil }