ruby-secret_service 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ .bundle
2
+ .DS_Store
3
+ vendor/bundle
4
+ default.pem
5
+ *.swo
6
+ resources_dump.json
7
+ hosts.txt
8
+ out
9
+ coverage
10
+ todo
11
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+ gem "woof_util"
5
+ gem "ruby-dbus"
6
+ gem "rake"
7
+ gem "bundler"
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ruby-secret_service (0.0.5)
5
+ ruby-dbus
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.2.4)
11
+ excon (0.16.10)
12
+ highline (1.6.19)
13
+ rake (10.1.0)
14
+ rspec (2.14.1)
15
+ rspec-core (~> 2.14.0)
16
+ rspec-expectations (~> 2.14.0)
17
+ rspec-mocks (~> 2.14.0)
18
+ rspec-core (2.14.5)
19
+ rspec-expectations (2.14.2)
20
+ diff-lcs (>= 1.1.3, < 2.0)
21
+ rspec-mocks (2.14.3)
22
+ ruby-dbus (0.9.2)
23
+ woof_util (0.0.16)
24
+ excon (~> 0.16.10)
25
+ highline (~> 1.6.15)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ bundler
32
+ rake
33
+ rspec
34
+ ruby-dbus
35
+ ruby-secret_service!
36
+ woof_util
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ Ruby Secret Service
2
+ ===================
3
+
4
+ Native Ruby bindings for [freedesktop.org's Secret Service](http://standards.freedesktop.org/secret-service/). Uses [ruby-dbus](https://github.com/mvidner/ruby-dbus).
5
+
6
+ ##Usage
7
+ ```
8
+ require "secret_service"
9
+
10
+ ss = SecretService.new
11
+
12
+ # create a secret in the default collection
13
+ name = "my github password"
14
+ secret = "s00p3r-s33|<r1+"
15
+
16
+ ss.collection.create_item(name, secret)
17
+
18
+ # and read it back
19
+ round_trip_secret = ss.collection.get_secret(name)
20
+ round_trip_secret == secret || raise "secret reading failed"
21
+
22
+ # create new collections!
23
+ other_coll_name = "other keyring"
24
+ other_name = "my heroku password"
25
+ other_secret = "1m s00 l33t"
26
+ ss.create_collection(other_coll_name)
27
+
28
+ ss.collection(other_coll_name).create_item(other_name, other_secret)
29
+ round_trip_other = ss.collection(other_coll_name).get_secret(other_name)
30
+ round_trip_other == other_secret || raise "can't read alt collection secret"
31
+ ```
32
+
33
+ ## Caveats
34
+
35
+ * Both KWallet and GNOME Keyring _REQUIRE_ the use of X11 to prompt
36
+ the user to decrypt ("unlock") the keychain. While you can use
37
+ this in a terminal-only environment (e.g., ssh'd in from a
38
+ desktop/laptop without X11), you're going to get errors about
39
+ having to unlock collections, but there is literally no way in the
40
+ spec to pass the decryption password over DBus.
41
+ * This is written chiefly to provide a programmatic access to
42
+ Secret Service for one specific program - Heroku Toolbelt. While
43
+ there's some basic support for multiple collections and
44
+ locking/unlocking, if you're doing anything moderately complex,
45
+ you're potentially better off [doing this in Python](https://bitbucket.org/kang/python-keyring-lib/overview)
46
+
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/setup"
2
+ require "rspec/core/rake_task"
3
+ require "woof_util/gem_rake_tasks"
4
+
5
+ RSpec::Core::RakeTask.new "spec"
6
+ WoofUtil::GemRakeTasks.create_tasks
7
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.5
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'secret_service'
4
+ require 'optparse'
5
+
6
+ options = {}
7
+ opts = OptionParser.new do |opts|
8
+ opts.banner = "Usage: #{$0} -s|-g NAME"
9
+ opts.on("-g", "--get NAME",
10
+ "Reads existing secret called NAME, prints secret to stdout") do |key|
11
+ options[:name] = key
12
+ options[:mode] = :get
13
+ end
14
+ opts.on("-s", "--set NAME",
15
+ "Creates new secret called NAME, reads secret from stdin") do |key|
16
+ options[:name] = key
17
+ options[:mode] = :set
18
+ end
19
+ end
20
+ opts.parse!
21
+
22
+ ss = SecretService.new
23
+
24
+ case options[:mode]
25
+ when :set
26
+ new_secret = STDIN.read
27
+ typeinfo = nil
28
+ attrs = ["a{ss}", {"name" => options[:name].to_s }]
29
+
30
+ properties =
31
+ {"org.freedesktop.Secret.Item.Label" => options[:name],
32
+ "org.freedesktop.Secret.Item.Attributes" => attrs
33
+ }
34
+ item = ss.collection.create_item properties, new_secret
35
+ when :get
36
+ item = ss.collection.unlocked_items({"name" => options[:name]})[0]
37
+ puts item.get_secret
38
+ else
39
+ puts opts.help
40
+ exit 1
41
+ end
42
+
43
+ exit 0
44
+ name = ARGV[0]
45
+
46
+ item = ss.collection.unlocked_items({"name" => name})[0]
47
+ puts "label: #{item.label}"
48
+ puts "last modified #{item.modified}, locked: #{item.locked?}"
49
+ puts "attributes: #{item.attributes.to_s}"
50
+
51
+ # item.attributes = ["name", "test2"]
52
+ # {"magic" => "secret_service.rb", "name" => "test"}
53
+
54
+
55
+ #item = SecretService::Item.new(ss.bus, secret_path)
56
+
57
+ #puts item.your_mom
58
+
59
+ #puts ss.init_session[1]
60
+
61
+ #item = SecretService::Item.new(session, secret_path)
62
+ #
63
+ #puts item.item["Modified"].class
64
+
@@ -0,0 +1,89 @@
1
+ class SecretService
2
+ class Collection
3
+ attr_accessor :service, :name, :path
4
+
5
+ def initialize(service, name = DEFAULT_COLLECTION, path=nil)
6
+ @service = service
7
+ @name = name
8
+ @path = path || "#{COLLECTION_PREFIX}#{name}"
9
+ @proxy = @service.get_proxy(@path, IFACE[:collection])
10
+ end
11
+
12
+ def lock!
13
+ locked_objs, prompt_path = @service.proxy.Lock [@path]
14
+ return true if prompt_path == "/" and locked_objs.include?(@path)
15
+
16
+ # need to do the prompt dance
17
+ @service.prompt!(prompt_path)
18
+ locked?
19
+ end
20
+
21
+ def unlock!
22
+ unlocked_objs, prompt_path = @service.proxy.Unlock [@path]
23
+ return true if prompt_path == "/" and unlocked_objs.include?(@path)
24
+
25
+ #nuts, stupid prompt
26
+ @service.prompt!(prompt_path)
27
+ ! locked?
28
+ end
29
+
30
+ def locked?
31
+ get_property(:locked)
32
+ end
33
+
34
+ def set_property name, new_val
35
+ @proxy.Set(IFACE[:item], name.to_s.downcase.capitalize, new_val)
36
+ end
37
+
38
+ def get_property name
39
+ @proxy.Get(IFACE[:collection], name.to_s.downcase.capitalize)[0]
40
+ end
41
+
42
+ def session
43
+ @service.session
44
+ end
45
+
46
+ def unlocked_items(search_pred = {})
47
+ @proxy.SearchItems(search_pred)[0].map {|path| Item.new self, path }
48
+ end
49
+
50
+ def locked_items(search_pref = {})
51
+ @proxy.SearchItems(search_pred)[1].map {|path| Item.new self, path }
52
+ end
53
+
54
+ def create_item name, secret, properties=nil, replace=true
55
+ if properties.nil?
56
+ # ruby-dbus's type inference system doesn't handle recursion for
57
+ # vaguely complicated structs, yet the protocol requires
58
+ # explicit type annotation. Consequently, nontrivial structs
59
+ # require the user to provide their own annotation
60
+ attrs = ["a{ss}", {"name" => name.to_s }]
61
+
62
+ properties =
63
+ {"#{SS_PREFIX}Item.Label" => name.to_s,
64
+ "#{SS_PREFIX}Item.Attributes" => attrs
65
+ }
66
+ end
67
+ result = @proxy.CreateItem(properties, secret_encode(secret), replace)
68
+ new_item_path = result[0]
69
+ Item.new(self, new_item_path)
70
+ end
71
+
72
+ def get_secret name
73
+ (unlocked_items({"name" => name})[0]).get_secret
74
+ end
75
+
76
+ def secret_encode secret_string
77
+ mime_type = "application/octet-stream"
78
+
79
+ if(secret_string.respond_to? "encoding" and
80
+ secret_string.encoding.to_s != "ASCII-8BIT")
81
+ secret_string.encode! "UTF-8"
82
+ #mime_type = "text/plain; charset=utf8"
83
+ end
84
+
85
+ [session[1], [], secret_string.bytes.to_a, mime_type]
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,87 @@
1
+ class SecretService
2
+ class Item
3
+
4
+ attr_accessor :path
5
+
6
+ def initialize(collection, path)
7
+ @collection = collection
8
+ @path = path
9
+ @proxy = collection.service.get_proxy @path, IFACE[:item]
10
+ end
11
+
12
+ def modified
13
+ Time.at get_property(:modified)
14
+ end
15
+
16
+ def created
17
+ Time.at get_property(:created)
18
+ end
19
+
20
+ def locked?
21
+ get_property(:locked)
22
+ end
23
+
24
+ def lock!
25
+ locked, prompt_path = @collection.service.proxy.Lock [@path]
26
+ return true if prompt_path == "/" and locked.include? @path
27
+
28
+ # otherwise we have to handle the prompt
29
+ @collection.service.prompt!(prompt_path)
30
+ get_property(:locked)
31
+ end
32
+
33
+ def label
34
+ get_property(:label)
35
+ end
36
+
37
+ def label= new_label
38
+ set_property(:label, new_label)
39
+ end
40
+
41
+ def attributes
42
+ get_property(:attributes)
43
+ end
44
+
45
+ # TODO: this keeps throwing type errors
46
+ def attributes= new_attrs
47
+ set_property(:attributes, new_attrs)
48
+ end
49
+
50
+ def set_property name, new_val
51
+ @proxy.Set(IFACE[:item], name.to_s.downcase.capitalize, new_val)
52
+ end
53
+
54
+ def get_property name
55
+ @proxy.Get(IFACE[:item], name.to_s.downcase.capitalize)[0]
56
+ end
57
+
58
+ def session
59
+ @collection.session
60
+ end
61
+
62
+ def get_secret
63
+ secret_decode(@proxy.GetSecret(session[1]))
64
+ end
65
+
66
+ # http://standards.freedesktop.org/secret-service/ch14.html#type-Secret
67
+ def secret_decode secret_arr
68
+ secret_struct = secret_arr[0]
69
+ s = {}
70
+ [:session, :params, :bytes, :mime].each do |x|
71
+ s[x] = secret_struct.shift
72
+ end
73
+
74
+ secret_string = (s[:bytes].map {|x| x.chr}).join
75
+ if(secret_string.respond_to? "encoding" and
76
+ s[:mime] != "application/octet-stream")
77
+ charset = s[:mime].match(/charset=(.+)/)[1]
78
+ unless charset.nil?
79
+ charset.upcase!.sub! /\AUTF([\w\d])/, "UTF-#{$1}"
80
+ secret_string.force_encoding charset
81
+ end
82
+ end
83
+ secret_string
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,30 @@
1
+ class SecretService
2
+ class Prompt
3
+
4
+ attr_accessor :path
5
+
6
+ class NoPromptRequired < Exception ; end
7
+
8
+ def initialize service, object_path
9
+ raise NoPromptRequired if object_path == "/"
10
+ @service = service
11
+ @path = object_path
12
+ @proxy = service.get_proxy object_path, SecretService::IFACE[:prompt]
13
+ end
14
+
15
+ def prompt!
16
+ loop = DBus::Main.new
17
+ loop << @service.bus
18
+ @proxy.on_signal("Completed") do |dismissed, result|
19
+ loop.quit
20
+ end
21
+ @proxy.Prompt ""
22
+ loop.run
23
+ end
24
+
25
+ def dismiss
26
+ @proxy.Dismiss
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,86 @@
1
+ # http://standards.freedesktop.org/secret-service/ch14.html#id481899
2
+ # Creating a "secret"
3
+
4
+ class SecretService
5
+ class Secret
6
+
7
+ attr_accessor :session_path, :parameters, :content_type
8
+
9
+ def initialize attrs
10
+ @session_path = attrs[:session_path]
11
+ @parameters = attrs[:parameters] || []
12
+ @value = attrs[:value]
13
+ @content_type = attrs[:content_type] || sniff_content_type(@value)
14
+ end
15
+
16
+ def value
17
+ @value
18
+ end
19
+
20
+ def value= val
21
+ @value = val
22
+ @content_type = sniff_content_type attrs[:value]
23
+ end
24
+
25
+ # Create a new SecretService::Secret from the DBus Struct format
26
+ def self.from_struct s
27
+ initialize(:session_path => s[0][0],
28
+ :parameters => s[0][1],
29
+ :value => (s[0][2].map {|x| x.chr}).join,
30
+ :content_type => (s[0][3] == "") ? nil : s[0][3]
31
+ )
32
+ end
33
+
34
+ # Convert the human-readable version into the format expected
35
+ # by DBus.
36
+ def to_struct
37
+ [ "(oayays)",
38
+ [@session_path, @parameters, @value.bytes.to_a, @content_type]
39
+ ]
40
+ end
41
+
42
+
43
+ # Take a string, guess what the Content-type should be.
44
+ # For Ruby < 1.9, assume binary encoding. You can avoid this
45
+ # by passing in an explicit content_type to the initializer.
46
+ #
47
+ # Or, y'know, using a more recent version of the language.
48
+ def sniff_content_type str
49
+ if (str.nil? or
50
+ (not str.respond_to? :encoding ) or
51
+ (str.encoding.to_s == "ASCII-8BIT"))
52
+ "application/octet-stream"
53
+ else
54
+ "text/plain; charset=#{str.encoding}"
55
+ end
56
+ end
57
+
58
+ # Derive the Ruby String encoding from a given Content-type.
59
+ # When all else fails, assumes ASCII-8BIT (aka Binary)
60
+ def self.content_type_to_encoding content_type=nil
61
+ binary = "ASCII-8BIT"
62
+
63
+ begin
64
+ case charset = content_type.match(/; charset=(.+)\z/)[1].upcase
65
+ when /\AUTF[^-]/
66
+ # "UTF8" is a common misspelling of "UTF-8".
67
+ charset.sub! /\AUTF/, "UTF-"
68
+ when /./
69
+ # Accept charset.upcase at face value & hope for the best
70
+ charset
71
+ else
72
+ # This is a technical violation of RFC 2616, sec. 3.7.1, which
73
+ # states ISO-8859-1 is the default for "text/*" when no
74
+ # charset is specified. However, I claim UTF-8 is a safer
75
+ # assumption on the modern Internet.
76
+ charset = content_type.match(/\Atext\//) ? "UTF-8" : binary
77
+ end
78
+ "".encode charset
79
+ charset
80
+ rescue
81
+ binary
82
+ end
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,96 @@
1
+ require 'dbus'
2
+
3
+ require 'secret_service/collection'
4
+ require 'secret_service/item'
5
+ require 'secret_service/secret'
6
+ require 'secret_service/prompt'
7
+
8
+ class SecretService
9
+ SECRETS = 'org.freedesktop.secrets'
10
+ SS_PREFIX = 'org.freedesktop.Secret.'
11
+ SS_PATH = '/org/freedesktop/secrets'
12
+ COLLECTION_PREFIX = '/org/freedesktop/secrets/aliases/'
13
+ DEFAULT_COLLECTION = "default"
14
+
15
+ ALGO = "plain"
16
+
17
+ DBUS_UNKNOWN_METHOD = 'org.freedesktop.DBus.Error.UnknownMethod'
18
+ DBUS_SERVICE_UNKNOWN = 'org.freedesktop.DBus.Error.ServiceUnknown'
19
+ DBUS_EXEC_FAILED = 'org.freedesktop.DBus.Error.Spawn.ExecFailed'
20
+ DBUS_NO_REPLY = 'org.freedesktop.DBus.Error.NoReply'
21
+ DBUS_NO_SUCH_OBJECT = 'org.freedesktop.Secret.Error.NoSuchObject'
22
+
23
+ IFACE = {}
24
+ [:service, :item, :collection, :prompt].each do |x|
25
+ IFACE[x] = "#{SS_PREFIX}#{x.to_s.capitalize}"
26
+ end
27
+
28
+ attr_accessor :bus, :proxy
29
+
30
+ class NoSessionBus < Exception
31
+ end
32
+
33
+ def initialize
34
+ begin
35
+ @bus = DBus::SessionBus.instance
36
+
37
+ @proxy_maker = @bus.service SECRETS
38
+ @proxy = get_proxy SS_PATH, IFACE[:service]
39
+ @collections = {}
40
+
41
+ @collection_paths = self.list_collections
42
+ rescue
43
+ raise NoSessionBus
44
+ end
45
+ end
46
+
47
+ def get_proxy path, iface=nil
48
+ obj = @proxy_maker.object path
49
+ obj.introspect
50
+ obj.default_iface = iface unless iface.nil?
51
+ obj
52
+ end
53
+
54
+ def session
55
+ @session ||= @proxy.OpenSession(ALGO, "")
56
+ end
57
+
58
+ def collection(name=DEFAULT_COLLECTION, path=nil)
59
+ @collections[name.to_s] ||= Collection.new(self, name, path)
60
+ end
61
+
62
+ def list_collections
63
+ @proxy.Get(IFACE[:service], 'Collections')
64
+ end
65
+
66
+ def create_collection name, properties=nil
67
+ properties ||= {"#{SS_PREFIX}Collection.Label" => name}
68
+
69
+ coll, prompt_path = @proxy.CreateCollection properties, ""
70
+ prompt!(prompt_path) if prompt_path != "/"
71
+ collection(name, coll)
72
+ end
73
+
74
+
75
+ def set_alias name, collection
76
+ @proxy.SetAlias name, (collection.class == String ? collection : collection.path)
77
+ end
78
+
79
+ def read_alias name
80
+ path = @proxy.ReadAlias name
81
+ collection(name, path)
82
+ end
83
+
84
+ def search_items attrs={}
85
+ @proxy.SearchItems(attrs)
86
+ end
87
+
88
+ def unlock objects
89
+ @proxy.Unlock objects
90
+ end
91
+
92
+ def prompt!(prompt_path)
93
+ SecretService::Prompt.new(self, prompt_path).prompt!
94
+ end
95
+
96
+ end
@@ -0,0 +1,19 @@
1
+ require 'find'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'ruby-secret_service'
5
+ s.version = File.read("VERSION").chomp
6
+ s.summary = 'Ruby bindings for GNOME Keyring & KWallet'
7
+ s.description = "Native bindings use the D-BUS Secret Service API, docs at http://standards.freedesktop.org/secret-service/"
8
+ s.authors = ["Tom Maher"]
9
+ s.email = "tmaher@pw0n.me"
10
+ s.license = "Apache 2.0"
11
+ s.files = `git ls-files`.split("\n")
12
+ s.require_path = ["lib"]
13
+ s.homepage = "https://github.com/tmaher/ruby-secret_service"
14
+ s.add_development_dependency "woof_util"
15
+ s.add_development_dependency "rake"
16
+ s.add_development_dependency "rspec"
17
+
18
+ s.add_dependency "ruby-dbus"
19
+ end
data/spec/rss_spec.rb ADDED
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe SecretService do
4
+
5
+ #it "aborts when it can't find dbus" do
6
+ #state = hide_dbus_configs
7
+ #SecretService.new
8
+ #expect {SecretService.new}.to raise_error
9
+ #restore_dbus_configs state
10
+ #end
11
+
12
+ it "can create a session" do
13
+ SecretService.new.class.should_not be nil
14
+ end
15
+
16
+ it "has a default collection" do
17
+ SecretService.new.collection.should_not be nil
18
+ end
19
+
20
+ it "can lock and unlock collections" do
21
+ ss = SecretService.new
22
+ ss.collection.lock!.should eq true
23
+ ss.collection.locked?.should eq true
24
+ ss.collection.unlock!.should eq true
25
+ ss.collection.locked?.should eq false
26
+ end
27
+
28
+ it "can create and read back objects" do
29
+ name = SecureRandom.hex(8).to_s
30
+ secret = SecureRandom.hex(8).to_s
31
+ ss = SecretService.new
32
+ ss.collection.unlock!
33
+ ss.collection.create_item("rspec_test_#{name}", secret).should_not be nil
34
+ ss.collection.get_secret("rspec_test_#{name}").should eq secret
35
+ end
36
+
37
+ it "can create a new collection" do
38
+ ss = SecretService.new
39
+ coll_label = "rspec_test_collection_#{SecureRandom.hex(4)}"
40
+ new_coll = ss.create_collection coll_label
41
+ new_coll.should_not be nil
42
+ new_coll.name.should eq coll_label
43
+ end
44
+
45
+ it "can create and lock objects" do
46
+ name = SecureRandom.hex(8).to_s
47
+ secret = SecureRandom.hex(8).to_s
48
+ ss = SecretService.new
49
+ item = ss.collection.create_item("rspec_test_#{name}", secret)
50
+ item.lock!
51
+ item.locked?.should eq true
52
+ end
53
+
54
+ it "can find objects" do
55
+ ss = SecretService.new
56
+ unlocked, locked = ss.search_items
57
+ unlocked.kind_of?(Array).should eq true
58
+ locked.kind_of?(Array).should eq true
59
+ (locked + unlocked).each do |item|
60
+ item.match(/^\/org\/freedesktop\/secrets\/collection/).nil?.should eq false
61
+ end
62
+ end
63
+
64
+ it "can unlock objects" do
65
+ ss = SecretService.new
66
+ item_paths, prompt = ss.unlock(ss.search_items[1])
67
+ end
68
+
69
+ it "aborts on invalid prompt creation" do
70
+ ss = SecretService.new
71
+ expect {ss.prompt! "/"}.to raise_error SecretService::Prompt::NoPromptRequired
72
+ end
73
+
74
+ #it "can raise a prompt" do
75
+ #ss = SecretService.new
76
+ #item_paths, prompt = ss.unlock(ss.search_items[1])
77
+ #ss.prompt!(prompt)
78
+ #new_items, new_prompt = ss.unlock(ss.search_items[1])
79
+ #new_prompt.should be_nil
80
+ #puts "new_items: #{new_items}"
81
+ #end
82
+
83
+ end
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'securerandom'
4
+
5
+ $: << File.dirname(__FILE__) + '/../lib'
6
+
7
+ require 'secret_service'
8
+
9
+ RSpec.configure do |config|
10
+ config.color_enabled = true
11
+ config.order = 'random'
12
+ config.seed = SecureRandom.random_number(2 ** 24)
13
+
14
+ # Use color not only in STDOUT but also in pagers and files
15
+ config.tty = true
16
+
17
+ # Use the specified formatter
18
+ #config.formatter = :documentation # :progress, :html, :textmate
19
+ end
20
+
21
+ def hide_dbus_configs
22
+ state = {:addr => ENV["DBUS_SESSION_BUS_ADDRESS"],
23
+ :display => ENV["DISPLAY"],
24
+ :dir => File.join(ENV["HOME"], ".dbus-#{SecureRandom.hex(4)}")
25
+ }
26
+ ENV.delete "DBUS_SESSION_BUS_ADDRESS"
27
+ ENV.delete "DISPLAY"
28
+ begin
29
+ File.rename File.join(ENV["HOME"], ".dbus"), state[:dir]
30
+ rescue; end
31
+ state
32
+ end
33
+
34
+ def restore_dbus_configs state
35
+ ENV["DBUS_SESSION_BUS_ADDRESS"] = state[:addr]
36
+ ENV["DISPLAY"] = state[:display]
37
+ begin
38
+ File.rename state[:dir], File.join(ENV["HOME"], ".dbus")
39
+ rescue; end
40
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-secret_service
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tom Maher
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-08-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: woof_util
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: ruby-dbus
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Native bindings use the D-BUS Secret Service API, docs at http://standards.freedesktop.org/secret-service/
79
+ email: tmaher@pw0n.me
80
+ executables: []
81
+ extensions: []
82
+ extra_rdoc_files: []
83
+ files:
84
+ - .gitignore
85
+ - Gemfile
86
+ - Gemfile.lock
87
+ - README.md
88
+ - Rakefile
89
+ - VERSION
90
+ - bin/secretservice.rb
91
+ - lib/secret_service.rb
92
+ - lib/secret_service/collection.rb
93
+ - lib/secret_service/item.rb
94
+ - lib/secret_service/prompt.rb
95
+ - lib/secret_service/secret.rb
96
+ - ruby-secret_service.gemspec
97
+ - spec/rss_spec.rb
98
+ - spec/spec_helper.rb
99
+ homepage: https://github.com/tmaher/ruby-secret_service
100
+ licenses:
101
+ - Apache 2.0
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 1.8.23
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: Ruby bindings for GNOME Keyring & KWallet
124
+ test_files: []