keyring 0.1.0
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/History.txt +4 -0
- data/README.md +70 -0
- data/Rakefile +17 -0
- data/lib/keyring.rb +15 -0
- data/lib/keyring/Keyring.rb +95 -0
- data/lib/keyring/SimpleKeyring.rb +38 -0
- data/spec/keyring_spec.rb +129 -0
- data/spec/spec_helper.rb +15 -0
- data/version.txt +1 -0
- metadata +77 -0
data/History.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
keyring
|
2
|
+
===========
|
3
|
+
|
4
|
+
A simple framework for storing passwords in certain keyring systems.
|
5
|
+
This gem is heavily inspired by python-keyring.
|
6
|
+
|
7
|
+
Examples
|
8
|
+
--------
|
9
|
+
|
10
|
+
The simplest case is to use a single global keyring instance:
|
11
|
+
|
12
|
+
require "keyring"
|
13
|
+
Keyring.set_password("service", "user", "password")
|
14
|
+
Keyring.get_password("service", "user") == "password"
|
15
|
+
|
16
|
+
This instance parses ./.rbkeyringrc and ~/.rbkeyringrc (in that order)
|
17
|
+
for a valid configuration. The configuration determines the default
|
18
|
+
module to use along with some parameters, e.g., the following
|
19
|
+
configuration uses the kwallet module (available as keyring-kwallet
|
20
|
+
gem):
|
21
|
+
|
22
|
+
---
|
23
|
+
module: keyring-kwallet
|
24
|
+
params:
|
25
|
+
folder: myfolder
|
26
|
+
app: myapp
|
27
|
+
|
28
|
+
Alternatively you can create instances of your favourite keyring module:
|
29
|
+
|
30
|
+
simple = Keyring::SimpleKeyring.new
|
31
|
+
kwallet = Keyring::KWalletKeyring.new folder: "myfolder", app: "myapp"
|
32
|
+
simple.set_password("service", "user", kwallet.get_password("service", "user"))
|
33
|
+
|
34
|
+
The concrete parameters depend on the backend type.
|
35
|
+
|
36
|
+
Install
|
37
|
+
-------
|
38
|
+
|
39
|
+
gem install keyring
|
40
|
+
|
41
|
+
Author
|
42
|
+
------
|
43
|
+
|
44
|
+
Original author: Frank Fischer
|
45
|
+
|
46
|
+
License
|
47
|
+
-------
|
48
|
+
|
49
|
+
(The MIT License) FIXME (different license?)
|
50
|
+
|
51
|
+
Copyright (c) 2011 FIXME (author's name)
|
52
|
+
|
53
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
54
|
+
a copy of this software and associated documentation files (the
|
55
|
+
'Software'), to deal in the Software without restriction, including
|
56
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
57
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
58
|
+
permit persons to whom the Software is furnished to do so, subject to
|
59
|
+
the following conditions:
|
60
|
+
|
61
|
+
The above copyright notice and this permission notice shall be
|
62
|
+
included in all copies or substantial portions of the Software.
|
63
|
+
|
64
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
65
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
66
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
67
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
68
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
69
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
70
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
begin
|
3
|
+
require 'bones'
|
4
|
+
rescue LoadError
|
5
|
+
abort '### Please install the "bones" gem ###'
|
6
|
+
end
|
7
|
+
|
8
|
+
task :default => 'spec:run'
|
9
|
+
task 'gem:release' => 'spec:run'
|
10
|
+
|
11
|
+
Bones {
|
12
|
+
name 'keyring'
|
13
|
+
authors 'Frank Fischer'
|
14
|
+
email 'frank.fischer@mathematik.tu-chemnitz.de'
|
15
|
+
url 'http://darcsden.com/lyro/keyring'
|
16
|
+
}
|
17
|
+
|
data/lib/keyring.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
module Keyring
|
3
|
+
|
4
|
+
# :stopdoc:
|
5
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
6
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
7
|
+
VERSION = ::File.read(PATH + 'version.txt').strip
|
8
|
+
|
9
|
+
%w(Keyring.rb SimpleKeyring.rb).each do |fname|
|
10
|
+
require File.join(LIBPATH, "keyring", fname)
|
11
|
+
end
|
12
|
+
|
13
|
+
end # module Keyring
|
14
|
+
|
15
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Keyring
|
4
|
+
|
5
|
+
@keyring = nil
|
6
|
+
@backends = {}
|
7
|
+
|
8
|
+
# Registers a backend
|
9
|
+
def self.add_backend( name, backend )
|
10
|
+
@backends[name] = backend
|
11
|
+
end
|
12
|
+
|
13
|
+
# Changes the global default key-ring
|
14
|
+
def self.set_keyring( keyring )
|
15
|
+
raise ArgumentError, "Expected keyring" unless keyring.kind_of? Keyring
|
16
|
+
@keyring = keyring
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the global default keyring
|
20
|
+
def self.keyring
|
21
|
+
unless @keyring
|
22
|
+
@backends.each_value do |backend|
|
23
|
+
keyring = backend.new
|
24
|
+
if keyring.supported?
|
25
|
+
@keyring = keyring
|
26
|
+
break if keyring.recommended?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
@keyring
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.method_missing(name, *args, &block)
|
34
|
+
keyring.send(name, *args, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Base class for all Keyrings.
|
38
|
+
# All keyring backends should inherit from this class.
|
39
|
+
class Keyring
|
40
|
+
# Determines if this keyring is supported by the current platform.
|
41
|
+
# @return [true, false] whether the keyring is supported by the current platform
|
42
|
+
def supported?
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
# Determines if this keyring is recommended by the current platform.
|
47
|
+
# @return [true, false] whether the keyring is recommended by the current platform
|
48
|
+
def recommended?
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
# Sets the user password for a certain service.
|
53
|
+
# @param [String] service the name of the service
|
54
|
+
# @param [String] username the name of the user
|
55
|
+
# @param [String, nil] password the new password to be stored
|
56
|
+
def set_password( service, username, password )
|
57
|
+
raise NotImplementedError, "Setting a password is not supported"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Removes a user password for a certain service from the keyring.
|
61
|
+
# This is the same as setting the password to nil.
|
62
|
+
# @param [String] service the name of the service
|
63
|
+
# @param [String] username the name of the user
|
64
|
+
def delete_password( service, username )
|
65
|
+
set_password( service, username, nil )
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns the current user password for a certain service.
|
69
|
+
# @param [String] service the name of the service
|
70
|
+
# @param [String] username the name of the user
|
71
|
+
# @return [String, nil] the current password if available
|
72
|
+
def get_password( service, username )
|
73
|
+
raise NotImplementedError, "Retrieving a password is not supported"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# load keyring
|
79
|
+
[".rbkeyringrc", "#{File.join(ENV['HOME'], '.rbkeyringrc')}"].each do |fname|
|
80
|
+
begin
|
81
|
+
File.open(fname, "r") do |f|
|
82
|
+
puts "load #{fname}"
|
83
|
+
config = YAML::load(f.read)
|
84
|
+
if config
|
85
|
+
kr_module = config["module"]
|
86
|
+
require kr_module
|
87
|
+
set_keyring(@backends[kr_module].new config["parameters"])
|
88
|
+
break
|
89
|
+
end
|
90
|
+
end
|
91
|
+
rescue IOError, Errno::ENOENT
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Keyring
|
2
|
+
|
3
|
+
# Simple keyring holding all keys in memory.
|
4
|
+
class SimpleKeyring < Keyring
|
5
|
+
def initialize
|
6
|
+
@services = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def supported?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
def recommended?
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_password( service, username )
|
18
|
+
passwords = @services[service]
|
19
|
+
if passwords
|
20
|
+
passwords[username]
|
21
|
+
else
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_password( service, username, password )
|
27
|
+
passwords = @services[service]
|
28
|
+
unless passwords
|
29
|
+
passwords = {}
|
30
|
+
@services[service] = passwords
|
31
|
+
end
|
32
|
+
passwords[username] = password
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
add_backend("simple", SimpleKeyring)
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
|
2
|
+
require File.join(File.dirname(__FILE__), %w[spec_helper])
|
3
|
+
|
4
|
+
describe Keyring::Keyring, "after creation" do
|
5
|
+
before do
|
6
|
+
@keyring = Keyring::Keyring.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should not be supported" do
|
10
|
+
@keyring.supported?.should == false
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should not be recommended" do
|
14
|
+
@keyring.recommended?.should == false
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should raise an error when getting a password" do
|
18
|
+
lambda{@keyring.get_password("service", "user")}.should raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should raise an error when setting a password" do
|
22
|
+
lambda{@keyring.set_password("service", "user", "pass")}.should raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should raise an error when deleting a password" do
|
26
|
+
lambda{@keyring.delete_password("service", "user", "pass")}.should raise_error
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
describe Keyring::SimpleKeyring, "after creation" do
|
32
|
+
before do
|
33
|
+
@keyring = Keyring::SimpleKeyring.new
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should be supported" do
|
37
|
+
@keyring.supported?.should == true
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should not be recommended" do
|
41
|
+
@keyring.recommended?.should == false
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should return nil when getting a password" do
|
45
|
+
@keyring.get_password("service", "user").should == nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should not raise an error when setting a password" do
|
49
|
+
lambda{@keyring.set_password("service", "user", "pass")}.should_not raise_error
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should not raise an error when deleting a password" do
|
53
|
+
lambda{@keyring.delete_password("service", "user")}.should_not raise_error
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
describe Keyring::SimpleKeyring, "with a single password" do
|
59
|
+
before do
|
60
|
+
@keyring = Keyring::SimpleKeyring.new
|
61
|
+
@keyring.set_password "service", "user", "pass"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should contain the password" do
|
65
|
+
@keyring.get_password("service", "user").should == "pass"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should not contain a password for another user" do
|
69
|
+
@keyring.get_password("service", "user2").should == nil
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should not contain a password for another service" do
|
73
|
+
@keyring.get_password("service2", "user").should == nil
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should not contain a password after deletion" do
|
77
|
+
@keyring.delete_password("service", "user")
|
78
|
+
@keyring.get_password("service", "user").should == nil
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should contain the password after deletion of another user" do
|
82
|
+
@keyring.delete_password("service", "user2")
|
83
|
+
@keyring.get_password("service", "user").should == "pass"
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should contain the password after deletion of another service" do
|
87
|
+
@keyring.delete_password("service2", "user")
|
88
|
+
@keyring.get_password("service", "user").should == "pass"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
describe Keyring::SimpleKeyring, "with a serveral passwords" do
|
94
|
+
before do
|
95
|
+
@keyring = Keyring::SimpleKeyring.new
|
96
|
+
@keyring.set_password "service", "user", "pass"
|
97
|
+
@keyring.set_password "service", "user2", "pass2"
|
98
|
+
@keyring.set_password "service2", "user", "pass21"
|
99
|
+
@keyring.set_password "service2", "user3", "pass23"
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should contain all passwords" do
|
103
|
+
@keyring.get_password("service", "user").should == "pass"
|
104
|
+
@keyring.get_password("service", "user2").should == "pass2"
|
105
|
+
@keyring.get_password("service2", "user").should == "pass21"
|
106
|
+
@keyring.get_password("service2", "user3").should == "pass23"
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should not contain a password for another user" do
|
110
|
+
@keyring.get_password("service", "user3").should == nil
|
111
|
+
@keyring.get_password("service2", "user2").should == nil
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should not contain a password after deletion" do
|
115
|
+
@keyring.delete_password("service", "user")
|
116
|
+
@keyring.get_password("service", "user").should == nil
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should contain the password after deletion of another user" do
|
120
|
+
@keyring.delete_password("service", "user2")
|
121
|
+
@keyring.get_password("service", "user").should == "pass"
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should contain the password after deletion of another service" do
|
125
|
+
@keyring.delete_password("service2", "user")
|
126
|
+
@keyring.get_password("service", "user").should == "pass"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
require File.expand_path(
|
3
|
+
File.join(File.dirname(__FILE__), %w[.. lib keyring]))
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
# == Mock Framework
|
7
|
+
#
|
8
|
+
# RSpec uses it's own mocking framework by default. If you prefer to
|
9
|
+
# use mocha, flexmock or RR, uncomment the appropriate line:
|
10
|
+
#
|
11
|
+
# config.mock_with :mocha
|
12
|
+
# config.mock_with :flexmock
|
13
|
+
# config.mock_with :rr
|
14
|
+
end
|
15
|
+
|
data/version.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: keyring
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Frank Fischer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-05-28 00:00:00 +02:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: bones
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 3.6.5
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
description: |-
|
28
|
+
A simple framework for storing passwords in certain keyring systems.
|
29
|
+
This gem is heavily inspired by python-keyring.
|
30
|
+
email: frank.fischer@mathematik.tu-chemnitz.de
|
31
|
+
executables: []
|
32
|
+
|
33
|
+
extensions: []
|
34
|
+
|
35
|
+
extra_rdoc_files:
|
36
|
+
- History.txt
|
37
|
+
files:
|
38
|
+
- History.txt
|
39
|
+
- README.md
|
40
|
+
- Rakefile
|
41
|
+
- lib/keyring.rb
|
42
|
+
- lib/keyring/Keyring.rb
|
43
|
+
- lib/keyring/SimpleKeyring.rb
|
44
|
+
- spec/keyring_spec.rb
|
45
|
+
- spec/spec_helper.rb
|
46
|
+
- version.txt
|
47
|
+
has_rdoc: true
|
48
|
+
homepage: http://darcsden.com/lyro/keyring
|
49
|
+
licenses: []
|
50
|
+
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options:
|
53
|
+
- --main
|
54
|
+
- README.md
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project: keyring
|
72
|
+
rubygems_version: 1.6.2
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: A simple framework for storing passwords in certain keyring systems.
|
76
|
+
test_files: []
|
77
|
+
|