The following patch does the following:

  Some changes to improve the naming of entries from 1Password:
  - Use the location as an alternate name, if there is no title
  - Use 'Untitled' if no reasonable name can be found.
  - Santize the filename, removing some characters that just cause
trouble.
  - Increment a suffix on the filename until we find one that's not in
use.
  - Rename pass[:name] to pass[:entryName] as there may be a name
field.

jf
-- 
John Franklin
[email protected]
commit 9959f2ed0605438af3253f3f812faef7dac238a0
Author: John Franklin <[email protected]>
Date:   Sun Jul 21 17:29:26 2019 -0400

    Some changes to improve the naming of entries from 1Password:
    - Use the location as an alternate name, if there is no title
    - Use 'Untitled' if no reasonable name can be found.
    - Santize the filename, removing some characters that just cause trouble.
    - Increment a suffix on the filename until we find one that's not in use.
    - Rename pass[:name] to pass[:entryName] as there may be a :name field.

diff --git a/contrib/importers/1password2pass.rb b/contrib/importers/1password2pass.rb
index e0ca39b..87cc6ba 100755
--- a/contrib/importers/1password2pass.rb
+++ b/contrib/importers/1password2pass.rb
@@ -23,9 +23,13 @@ accepted_formats = [".txt", ".1pif"]
 options = OpenStruct.new
 options.force = false
 options.name = :title
+options.altname = :location
 options.notes = true
 options.meta = true

+passroot = (ENV["PASSWORD_STORE_DIR"].to_s.empty?) ? ENV["HOME"] + "/.password-store" : ENV["PASSWORD_STORE_DIR"]
+abort("No such directory #{passroot}") if !File.exist?(passroot)
+
 optparse = OptionParser.new do |opts|
   opts.banner = "Usage: #{opts.program_name}.rb [options] filename"
   opts.on_tail("-h", "--help", "Display this screen") { puts opts; exit }
@@ -83,7 +87,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[:entryName] = "#{(options.group + "/") if options.group}#{entry[options.name]}"
     pass[:title] = entry[:title]
     pass[:password] = entry[:password]
     pass[:login] = entry[:username]
@@ -96,6 +100,7 @@ elsif File.extname(filename) =~ /.1pif/i
   require "json"

   options.name = :location if options.name == :url
+  options.altname = :name if options.name == :url

   # 1PIF is almost JSON, but not quite.  Remove the ***...*** lines
   # separating records, and then remove the trailing comma
@@ -108,7 +113,10 @@ elsif File.extname(filename) =~ /.1pif/i

     pass = {}

-    pass[:name] = "#{(options.group + "/") if options.group}#{entry[options.name]}"
+    entryName = entry[options.name].to_s.empty? ? entry[options.altname] : entry[options.name]
+    entryName = "Untitled" if entryName.to_s.empty?
+    entryName = entryName.gsub(/[:\*\[\]\|]/, "-")
+    pass[:entryName] = "#{(options.group + "/") if options.group}#{entryName}"

     pass[:title] = entry[:title]

@@ -133,7 +141,15 @@ puts "Read #{passwords.length} passwords."
 errors = []
 # Save the passwords
 passwords.each do |pass|
-  IO.popen("pass insert #{"-f " if options.force}-m \"#{pass[:name]}\" > /dev/null", "w") do |io|
+  base_fname = pass[:entryName].split('/').collect(&:strip).join('/') || "Untitled"
+  suffix=0
+  fname = "#{base_fname}"
+  exit if fname.empty?
+  while !options.force && (File.exists?("#{passroot}/#{fname}.gpg"))
+    suffix += 1
+    fname = "#{base_fname}-#{suffix.to_s}"
+  end
+  IO.popen("pass insert #{"-f " if options.force}-m \"#{fname}\" > /dev/null", "w") do |io|
     io.puts pass[:password]
     if options.meta
       io.puts "login: #{pass[:login]}" unless pass[:login].to_s.empty?
@@ -142,15 +158,15 @@ passwords.each do |pass|
     end
   end
   if $? == 0
-    puts "Imported #{pass[:name]}"
+    puts "Imported #{pass[:entryName]} to #{fname}"
   else
-    $stderr.puts "ERROR: Failed to import #{pass[:name]}"
+    $stderr.puts "ERROR: Failed to import #{pass[:entryName]}"
     errors << pass
   end
 end

 if errors.length > 0
-  $stderr.puts "Failed to import #{errors.map {|e| e[:name]}.join ", "}"
+  $stderr.puts "Failed to import #{errors.map {|e| e[:entryName]}.join ", "}"
   $stderr.puts "Check the errors. Make sure these passwords do not already "\
                "exist. If you're sure you want to overwrite them with the "\
                "new import, try again with --force."
_______________________________________________
Password-Store mailing list
[email protected]
https://lists.zx2c4.com/mailman/listinfo/password-store

Reply via email to