Class: Browserctl::State::Transports::OnePassword

Inherits:
Browserctl::State::Transport::Base show all
Defined in:
lib/browserctl/state/transports/one_password.rb

Overview

1Password transport — stores bundles as Documents. URIs look like ‘op://Vault/ItemName`.

The op CLI has no streaming primitive for documents, so we stage the blob to a tmpfile (chmod 0600) and use ‘op document create` / `op document get`.

Constant Summary collapse

SAFE_REF =
%r{\Aop://[^/]+/[^/]+\z}

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Browserctl::State::Transport::Base

#handles?

Class Method Details

.schemeObject



19
# File 'lib/browserctl/state/transports/one_password.rb', line 19

def self.scheme = "op"

Instance Method Details

#available?Boolean

Returns:

  • (Boolean)


21
22
23
# File 'lib/browserctl/state/transports/one_password.rb', line 21

def available?
  system("which", "op", out: ::File::NULL, err: ::File::NULL)
end

#parse_ref(uri) ⇒ Object



57
58
59
60
61
# File 'lib/browserctl/state/transports/one_password.rb', line 57

def parse_ref(uri)
  # op://Vault/Item — exactly two segments after the scheme
  rest = uri.delete_prefix("op://")
  rest.split("/", 2)
end

#read(parsed) ⇒ Object



25
26
27
28
29
30
31
32
# File 'lib/browserctl/state/transports/one_password.rb', line 25

def read(parsed)
  uri = parsed.to_s
  validate!(uri)
  out, err, status = Open3.capture3("op", "read", uri, binmode: true)
  return out if status.success?

  raise Transport::TransportError, "op read failed: #{err.strip.empty? ? out : err}"
end

#validate!(uri) ⇒ Object



51
52
53
54
55
# File 'lib/browserctl/state/transports/one_password.rb', line 51

def validate!(uri)
  return if SAFE_REF.match?(uri)

  raise Transport::TransportError, "invalid 1Password reference: #{uri.inspect} (expected op://Vault/Item)"
end

#write(parsed, blob) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/browserctl/state/transports/one_password.rb', line 34

def write(parsed, blob)
  uri = parsed.to_s
  validate!(uri)
  vault, title = parse_ref(uri)

  Dir.mktmpdir do |tmp|
    path = ::File.join(tmp, "#{title}.bctl")
    ::File.open(path, "wb", 0o600) { |f| f.write(blob) }

    args = ["op", "document", "create", path, "--title", title, "--vault", vault]
    out, err, status = Open3.capture3(*args)
    unless status.success?
      raise Transport::TransportError, "op document create failed: #{err.strip.empty? ? out : err}"
    end
  end
end