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

Reply via email to