diff --git a/Gemfile b/Gemfile index a431ee0..652120d 100644 --- a/Gemfile +++ b/Gemfile @@ -2,3 +2,5 @@ source "http://rubygems.org" # Specify your gem's dependencies in gpgme.gemspec gemspec + +gem 'rake' diff --git a/Rakefile b/Rakefile index a5d7588..819ef37 100644 --- a/Rakefile +++ b/Rakefile @@ -8,17 +8,18 @@ require 'yard' desc "Re-compile the extensions" task :compile do - FileUtils.rm_f('gpgme_n.bundle') - FileUtils.rm_f('gpgme_n.o') - FileUtils.rm_f('Makefile') + FileUtils.rm_rf('tmp') if File.directory?('tmp') + mkdir 'tmp' - system "ruby extconf.rb" - system "make" + Dir.chdir('tmp') do + system "ruby #{File.dirname(__FILE__)}/ext/gpgme/extconf.rb" + system "make" + end end task :default => [:test] -Rake::TestTask.new(:test) do |t| +Rake::TestTask.new(:test => :compile) do |t| t.libs << 'test' t.pattern = "test/**/*_test.rb" t.verbose = true diff --git a/lib/gpgme/key.rb b/lib/gpgme/key.rb index 85a8c3e..010e9b8 100644 --- a/lib/gpgme/key.rb +++ b/lib/gpgme/key.rb @@ -40,7 +40,7 @@ class << self # # @example # GPGME::Key.find(:public, "mrsimo@example.com", :sign) - # # => return the public keys that match mrsimo@exampl.com and are + # # => return the public keys that match mrsimo@example.com and are # # capable of signing def find(secret, keys_or_names = nil, purposes = []) secret = (secret == :secret) @@ -63,6 +63,26 @@ def find(secret, keys_or_names = nil, purposes = []) keys end + # Works similar as {.find}, however it restricts the way the keys are looked up. + # GPG has the issue that finding a key for bar@example.com, also returns a key + # for foobar@example.com. + # This can be restricted by adding <> around the address: . + # Hence {.find_exact} simply wraps <> around each email you passed to the method and delegates + # the rest to {.find} + # + # @example + # GPGME::Key.find_exact(:public, "bar@example.com") + # # => return the public key of bar@example.com, but not for + # # foobar@example.com + def find_exact(secret, keys_or_names = nil, purposes = []) + keys_or_names = [""] if keys_or_names.nil? || (keys_or_names.is_a?(Array) && keys_or_names.empty?) + find( + secret, + [keys_or_names].flatten.collect{|k| if k =~ /.*@.*/ && !(k =~ /<.*@.*>/) then "<#{k}>" else k end }, + purposes + ) + end + def get(fingerprint) Ctx.new do |ctx| ctx.get_key(fingerprint) diff --git a/test/key_test.rb b/test/key_test.rb index 5128b28..cc8bfeb 100644 --- a/test/key_test.rb +++ b/test/key_test.rb @@ -53,6 +53,28 @@ assert keys.empty? end end + + describe :find_exact do + it "wraps an email address with angle brackets" do + GPGME::Key.expects(:find).with(:public,[''],[]) + GPGME::Key.find_exact(:public,'bar@example.com') + end + + it "wraps multiple email addresses with angle brackets" do + GPGME::Key.expects(:find).with(:public,['',''],[]) + GPGME::Key.find_exact(:public,['bar@example.com','foo@example.com']) + end + + it "does not touch other strings than email addresses" do + GPGME::Key.expects(:find).with(:public,['Bar Example'],[]) + GPGME::Key.find_exact(:public,'Bar Example') + end + + it "does the same in mixed mode" do + GPGME::Key.expects(:find).with(:public,['','Foo Example'],[]) + GPGME::Key.find_exact(:public,['bar@example.com','Foo Example']) + end + end describe :export do # Testing the lazy way with expectations. I think tests in diff --git a/test/test_helper.rb b/test/test_helper.rb index e9d25c4..fe6f974 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,4 +1,12 @@ # -*- encoding: utf-8 -*- + +# include compiled gpgme_n.bundle +tmp_dir = File.join(File.dirname(__FILE__), '..', 'tmp') +$:.unshift(tmp_dir) if File.directory?(tmp_dir) + +# this interfers otherwise with our tests +ENV.delete('GPG_AGENT_INFO') + require 'rubygems' require 'bundler/setup' require 'minitest/autorun' @@ -10,6 +18,7 @@ require File.dirname(__FILE__) + "/support/resources" + def import_keys KEYS.each do |key| import_key(key)