Hey! I originally made the 1password2pass.rb import script. I host it separately on GitHub as well – https://github.com/tobiasvl/1password2pass – and have received some contributions for it there. I asked the contributors if they wanted to send the patches upstream to you, but never heard from them, so I'm sending them here on their behalf.
Please note: On May 25, 2016 I sent a small patch for this import script myself to this mailing list – the message ID for that e-mail is <CAHE5ZHk=bug3ef9TnPZVfmhQvRQM=6vhn_pdygaklpdbkeg...@mail.gmail.com>. It seems that patch was never acknowledged, nor applied. It can be discarded now, as it's no longer relevant after the attached patch #1. -- Tobias V. Langhoff
From 05ae1841d77f8e55fb301508b1ad1c8dd8e97cfb Mon Sep 17 00:00:00 2001 From: John Franklin <[email protected]> Date: Sun, 10 Jul 2016 02:23:07 -0400 Subject: [PATCH 2/3] Add some exception handling to prevent missing username or password fields from crashing the script. --- 1password2pass.rb | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/1password2pass.rb b/1password2pass.rb index e8d9d10..e8a3e56 100755 --- a/1password2pass.rb +++ b/1password2pass.rb @@ -110,17 +110,22 @@ elsif File.extname(filename) =~ /.1pif/i pass[:name] = "#{(options.group + "/") if options.group}#{entry[options.name]}" pass[:title] = entry[:title] - - pass[:password] = entry[:secureContents][:fields].detect do |field| - field[:designation] == "password" - end[:value] - - username = entry[:secureContents][:fields].detect do |field| - field[:designation] == "username" + begin + pass[:password] = entry[:secureContents][:fields].detect do |field| + field[:name] == "password" or field[:designation] == "password" + end[:value] + rescue + puts "WARNING: No password found in entry " + entry[:title] + pass[:password] = {} + end + begin + pass[:login] = entry[:secureContents][:fields].detect do |field| + field[:name] == "username" or field[:designation] == "username" + end[:value] + rescue + puts "WARNING: No username found in entry " + entry[:title] + pass[:login] = {} end - # might be nil - pass[:login] = username[:value] if username - pass[:url] = entry[:location] pass[:notes] = entry[:secureContents][:notesPlain] passwords << pass -- 2.13.6
From 536270b082263ccd508acab812d2f70594bb8399 Mon Sep 17 00:00:00 2001 From: John Franklin <[email protected]> Date: Sat, 9 Jul 2016 19:12:49 -0400 Subject: [PATCH 1/3] Parse 1pif files line by line --- 1password2pass.rb | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/1password2pass.rb b/1password2pass.rb index e0ca39b..e8d9d10 100755 --- a/1password2pass.rb +++ b/1password2pass.rb @@ -95,14 +95,13 @@ if File.extname(filename) =~ /.txt/i elsif File.extname(filename) =~ /.1pif/i require "json" - options.name = :location if options.name == :url + File.readlines(filename).each do |line| + next if line =~ /^\*\*\*/ + entry = JSON.parse(line, {symbolize_names: true}) - # 1PIF is almost JSON, but not quite. Remove the ***...*** lines - # separating records, and then remove the trailing comma - pif = File.open(filename).read.gsub(/^\*\*\*.*\*\*\*$/, ",").chomp.chomp(",") + options.name = :location if options.name == :url - # Import 1PIF - JSON.parse("[#{pif}]", symbolize_names: true).each do |entry| + # Import 1PIF next unless entry[:typeName] == "webforms.WebForm" next if entry[:secureContents][:fields].nil? -- 2.13.6
From 6025ec7165a4d334cc386eee71747a7f596b85a0 Mon Sep 17 00:00:00 2001 From: Felice Serena <[email protected]> Date: Tue, 18 Jul 2017 17:24:41 +0200 Subject: [PATCH 3/3] Added default name filtering --- 1password2pass.rb | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/1password2pass.rb b/1password2pass.rb index e8a3e56..26fb5dc 100755 --- a/1password2pass.rb +++ b/1password2pass.rb @@ -19,12 +19,26 @@ require "ostruct" accepted_formats = [".txt", ".1pif"] +def filter_name(name, pattern, replacement) + if replacement == false + return name + end + name_filtered = name.gsub(pattern, replacement) + if name_filtered != name + puts "WARNING: Changed entry name from '" + name + "' to '" + name_filtered + "'" + name = name_filtered + end + name +end + # Default options options = OpenStruct.new options.force = false options.name = :title options.notes = true options.meta = true +options.name_filter_pattern = /[\/\\]/ +options.name_filter_replacement = "_" optparse = OptionParser.new do |opts| opts.banner = "Usage: #{opts.program_name}.rb [options] filename" @@ -43,6 +57,10 @@ optparse = OptionParser.new do |opts| "Import metadata and insert it below the password") do |meta| options.meta = meta end + opts.on("-z", "--[no-]name-filter-replacement REPLACEMENT", + "Replaces critical symbols (\\,/,...) with REPLACEMENT. Default replacement is a single underscore (_).") do |sym| + options.name_filter_replacement = sym + end begin opts.parse! @@ -83,7 +101,7 @@ if File.extname(filename) =~ /.txt/i # Import CSV/TSV CSV.foreach(filename, {col_sep: delimiter, headers: true, header_converters: :symbol}) do |entry| pass = {} - pass[:name] = "#{(options.group + "/") if options.group}#{entry[options.name]}" + pass[:name] = "#{(options.group + "/") if options.group}#{filter_name(entry[options.name], options.name_filter_pattern, options.name_filter_replacement)}" pass[:title] = entry[:title] pass[:password] = entry[:password] pass[:login] = entry[:username] @@ -107,7 +125,7 @@ elsif File.extname(filename) =~ /.1pif/i pass = {} - pass[:name] = "#{(options.group + "/") if options.group}#{entry[options.name]}" + pass[:name] = "#{(options.group + "/") if options.group}#{filter_name(entry[options.name], options.name_filter_pattern, options.name_filter_replacement)}" pass[:title] = entry[:title] begin -- 2.13.6
_______________________________________________ Password-Store mailing list [email protected] https://lists.zx2c4.com/mailman/listinfo/password-store
