trocla 0.1.2 → 0.2.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.
- checksums.yaml +7 -7
- data/.travis.yml +4 -0
- data/Gemfile +4 -1
- data/README.md +164 -17
- data/bin/trocla +31 -16
- data/lib/VERSION +2 -2
- data/lib/trocla.rb +48 -28
- data/lib/trocla/default_config.yaml +33 -4
- data/lib/trocla/encryptions.rb +3 -2
- data/lib/trocla/encryptions/ssl.rb +8 -10
- data/lib/trocla/formats/x509.rb +57 -30
- data/lib/trocla/store.rb +74 -0
- data/lib/trocla/stores.rb +39 -0
- data/lib/trocla/stores/memory.rb +56 -0
- data/lib/trocla/stores/moneta.rb +54 -0
- data/lib/trocla/util.rb +22 -8
- data/spec/spec_helper.rb +235 -20
- data/spec/trocla/encryptions/none_spec.rb +22 -0
- data/spec/trocla/encryptions/ssl_spec.rb +2 -32
- data/spec/trocla/formats/x509_spec.rb +295 -0
- data/spec/trocla/store/memory_spec.rb +6 -0
- data/spec/trocla/store/moneta_spec.rb +6 -0
- data/spec/trocla/util_spec.rb +24 -12
- data/spec/trocla_spec.rb +109 -76
- data/trocla.gemspec +31 -22
- metadata +120 -84
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'trocla/store'
|
2
|
+
# store management
|
3
|
+
class Trocla::Stores
|
4
|
+
class << self
|
5
|
+
def [](store)
|
6
|
+
stores[store.to_s.downcase]
|
7
|
+
end
|
8
|
+
|
9
|
+
def all
|
10
|
+
@all ||= Dir[ path '*' ].collect do |store|
|
11
|
+
File.basename(store, '.rb').downcase
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def available?(store)
|
16
|
+
all.include?(store.to_s.downcase)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def stores
|
21
|
+
@@stores ||= Hash.new do |hash, store|
|
22
|
+
store = store.to_s.downcase
|
23
|
+
if File.exists?(path(store))
|
24
|
+
require "trocla/stores/#{store}"
|
25
|
+
class_name = "Trocla::Stores::#{store.capitalize}"
|
26
|
+
hash[store] = (eval class_name)
|
27
|
+
else
|
28
|
+
raise "Store #{store} is not supported!"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def path(store)
|
34
|
+
File.expand_path(
|
35
|
+
File.join(File.dirname(__FILE__), 'stores', "#{store}.rb")
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# a simple in memory store just as an example
|
2
|
+
class Trocla::Stores::Memory < Trocla::Store
|
3
|
+
attr_reader :memory
|
4
|
+
def initialize(config,trocla)
|
5
|
+
super(config,trocla)
|
6
|
+
@memory = Hash.new({})
|
7
|
+
end
|
8
|
+
|
9
|
+
def get(key,format)
|
10
|
+
unless expired?(key)
|
11
|
+
memory[key][format]
|
12
|
+
else
|
13
|
+
delete_all(key)
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
def set(key,format,value,options={})
|
18
|
+
super(key,format,value,options)
|
19
|
+
set_expires(key,options['expires'])
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def set_plain(key,value,options)
|
24
|
+
memory[key] = { 'plain' => value }
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_format(key,format,value,options)
|
28
|
+
memory[key].merge!({ format => value })
|
29
|
+
end
|
30
|
+
|
31
|
+
def delete_all(key)
|
32
|
+
memory.delete(key)
|
33
|
+
end
|
34
|
+
def delete_format(key,format)
|
35
|
+
old_val = (h = memory[key]).delete(format)
|
36
|
+
h.empty? ? memory.delete(key) : memory[key] = h
|
37
|
+
set_expires(key,nil)
|
38
|
+
old_val
|
39
|
+
end
|
40
|
+
private
|
41
|
+
def set_expires(key,expires)
|
42
|
+
expires = memory[key]['_expires'] if expires.nil?
|
43
|
+
if expires && expires > 0
|
44
|
+
memory[key]['_expires'] = expires
|
45
|
+
memory[key]['_expires_at'] = Time.now + expires
|
46
|
+
else
|
47
|
+
memory[key].delete('_expires')
|
48
|
+
memory[key].delete('_expires_at')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
def expired?(key)
|
52
|
+
memory.key?(key) &&
|
53
|
+
(a = memory[key]['_expires_at']).is_a?(Time) && \
|
54
|
+
(a < Time.now)
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# the default moneta based store
|
2
|
+
class Trocla::Stores::Moneta < Trocla::Store
|
3
|
+
attr_reader :moneta
|
4
|
+
def initialize(config,trocla)
|
5
|
+
super(config,trocla)
|
6
|
+
require 'moneta'
|
7
|
+
# load expire support by default
|
8
|
+
adapter_options = { :expires => true }.merge(
|
9
|
+
store_config['adapter_options']||{})
|
10
|
+
@moneta = Moneta.new(store_config['adapter'],adapter_options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(key,format)
|
14
|
+
moneta.fetch(key, {})[format]
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def set_plain(key,value,options)
|
19
|
+
h = { 'plain' => value }
|
20
|
+
mo = moneta_options(key,options)
|
21
|
+
if options['expires'] && options['expires'] > 0
|
22
|
+
h['_expires'] = options['expires']
|
23
|
+
else
|
24
|
+
# be sure that we disable the existing
|
25
|
+
# expires if nothing is set.
|
26
|
+
mo[:expires] = false
|
27
|
+
end
|
28
|
+
moneta.store(key,h,mo)
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_format(key,format,value,options)
|
32
|
+
moneta.store(key,
|
33
|
+
moneta.fetch(key,{}).merge({ format => value }),
|
34
|
+
moneta_options(key,options))
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete_all(key)
|
38
|
+
moneta.delete(key)
|
39
|
+
end
|
40
|
+
def delete_format(key,format)
|
41
|
+
old_val = (h = moneta.fetch(key,{})).delete(format)
|
42
|
+
h.empty? ? moneta.delete(key) : moneta.store(key,h,moneta_options(key,{}))
|
43
|
+
old_val
|
44
|
+
end
|
45
|
+
def moneta_options(key,options)
|
46
|
+
res = {}
|
47
|
+
if options.key?('expires')
|
48
|
+
res[:expires] = options['expires']
|
49
|
+
elsif e = moneta.fetch(key, {})['_expires']
|
50
|
+
res[:expires] = e
|
51
|
+
end
|
52
|
+
res
|
53
|
+
end
|
54
|
+
end
|
data/lib/trocla/util.rb
CHANGED
@@ -15,13 +15,18 @@ class Trocla
|
|
15
15
|
private
|
16
16
|
|
17
17
|
def charsets
|
18
|
-
@charsets ||=
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
@charsets ||= begin
|
19
|
+
h = {
|
20
|
+
'default' => chars,
|
21
|
+
'alphanumeric' => alphanumeric,
|
22
|
+
'shellsafe' => shellsafe,
|
23
|
+
'windowssafe' => windowssafe,
|
24
|
+
'numeric' => numeric,
|
25
|
+
'hexadecimal' => hexadecimal,
|
26
|
+
'consolesafe' => consolesafe,
|
27
|
+
}
|
28
|
+
h.each { |k, v| h[k] = v.uniq }
|
29
|
+
end
|
25
30
|
end
|
26
31
|
|
27
32
|
def chars
|
@@ -33,8 +38,14 @@ class Trocla
|
|
33
38
|
def windowssafe
|
34
39
|
@windowssafe ||= alphanumeric + windowssafe_chars
|
35
40
|
end
|
41
|
+
def consolesafe
|
42
|
+
@consolesafe ||= alphanumeric + consolesafe_chars
|
43
|
+
end
|
44
|
+
def hexadecimal
|
45
|
+
@hexadecimal ||= numeric + ('a'..'f').to_a
|
46
|
+
end
|
36
47
|
def alphanumeric
|
37
|
-
@alphanumeric ||= ('a'..'z').to_a + ('A'..'Z').to_a +
|
48
|
+
@alphanumeric ||= ('a'..'z').to_a + ('A'..'Z').to_a + numeric
|
38
49
|
end
|
39
50
|
def numeric
|
40
51
|
@numeric ||= ('0'..'9').to_a
|
@@ -48,6 +59,9 @@ class Trocla
|
|
48
59
|
def windowssafe_chars
|
49
60
|
@windowssafe_chars ||= "+%/@=?_.,".split(//)
|
50
61
|
end
|
62
|
+
def consolesafe_chars
|
63
|
+
@consolesafe_chars ||= '+.-,_'.split(//)
|
64
|
+
end
|
51
65
|
end
|
52
66
|
end
|
53
67
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
3
|
require 'rspec'
|
4
|
-
require '
|
4
|
+
require 'rspec/pending_for'
|
5
5
|
require 'yaml'
|
6
6
|
require 'trocla'
|
7
7
|
|
@@ -9,8 +9,219 @@ require 'trocla'
|
|
9
9
|
# in ./support/ and its subdirectories.
|
10
10
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
11
11
|
|
12
|
-
RSpec.
|
13
|
-
|
12
|
+
RSpec.shared_examples "encryption_basics" do
|
13
|
+
describe 'storing' do
|
14
|
+
it "random passwords" do
|
15
|
+
expect(@trocla.password('random1', 'plain').length).to eql(16)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "long random passwords" do
|
19
|
+
expect(@trocla.set_password('random1_long','plain',4096.times.collect{|s| 'x' }.join('')).length).to eql(4096)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'retrieve' do
|
24
|
+
it "random passwords" do
|
25
|
+
stored = @trocla.password('random1', 'plain')
|
26
|
+
retrieved = @trocla.password('random1', 'plain')
|
27
|
+
retrieved_again = @trocla.password('random1', 'plain')
|
28
|
+
expect(retrieved).to eql(stored)
|
29
|
+
expect(retrieved_again).to eql(stored)
|
30
|
+
expect(retrieved_again).to eql(retrieved)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "encrypted passwords" do
|
34
|
+
@trocla.set_password('some_pass', 'plain', 'super secret')
|
35
|
+
expect(@trocla.get_password('some_pass', 'plain')).to eql('super secret')
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
describe 'deleting' do
|
40
|
+
it "plain" do
|
41
|
+
@trocla.set_password('some_pass', 'plain', 'super secret')
|
42
|
+
expect(@trocla.delete_password('some_pass', 'plain')).to eql('super secret')
|
43
|
+
end
|
44
|
+
it "delete formats" do
|
45
|
+
plain = @trocla.password('some_mysqlpass', 'plain')
|
46
|
+
mysql = @trocla.password('some_mysqlpass', 'mysql')
|
47
|
+
expect(@trocla.delete_password('some_mysqlpass', 'mysql')).to eql(mysql)
|
48
|
+
expect(@trocla.delete_password('some_mysqlpass', 'plain')).to eql(plain)
|
49
|
+
expect(@trocla.get_password('some_mysqlpass','plain')).to be_nil
|
50
|
+
expect(@trocla.get_password('some_mysqlpass','mysql')).to be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it "all passwords" do
|
54
|
+
plain = @trocla.password('some_mysqlpass', 'plain')
|
55
|
+
mysql = @trocla.password('some_mysqlpass', 'mysql')
|
56
|
+
deleted = @trocla.delete_password('some_mysqlpass')
|
57
|
+
expect(deleted).to be_a_kind_of(Hash)
|
58
|
+
expect(deleted['plain']).to eql(plain)
|
59
|
+
expect(deleted['mysql']).to eql(mysql)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
RSpec.shared_examples "verify_encryption" do
|
64
|
+
it "does not store plaintext passwords" do
|
65
|
+
@trocla.set_password('noplain', 'plain', 'plaintext_password')
|
66
|
+
expect(File.readlines(trocla_yaml_file).grep(/plaintext_password/)).to be_empty
|
67
|
+
end
|
68
|
+
|
69
|
+
it "makes sure identical passwords do not match when stored" do
|
70
|
+
@trocla.set_password('one_key', 'plain', 'super secret')
|
71
|
+
@trocla.set_password('another_key', 'plain', 'super secret')
|
72
|
+
yaml = YAML.load_file(trocla_yaml_file)
|
73
|
+
expect(yaml['one_key']['plain']).not_to eq(yaml['another_key']['plain'])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
RSpec.shared_examples 'store_validation' do |store|
|
78
|
+
describe '.get' do
|
79
|
+
it { expect(store.get('some_key','plain')).to be_nil }
|
80
|
+
end
|
81
|
+
describe '.set' do
|
82
|
+
it 'stores nil values' do
|
83
|
+
store.set('some_nil_value','plain',nil)
|
84
|
+
expect(store.get('some_nil_value','plain')).to be_nil
|
85
|
+
end
|
86
|
+
it 'stores plain format' do
|
87
|
+
store.set('some_value','plain','value')
|
88
|
+
expect(store.get('some_value','plain')).to eql('value')
|
89
|
+
end
|
90
|
+
it 'stores other formats' do
|
91
|
+
store.set('some_value','foo','bla')
|
92
|
+
expect(store.get('some_value','foo')).to eql('bla')
|
93
|
+
end
|
94
|
+
it 'resets other formats on setting plain' do
|
95
|
+
store.set('some_value','foo','bla')
|
96
|
+
store.set('some_value','plain','value')
|
97
|
+
expect(store.get('some_value','plain')).to eql('value')
|
98
|
+
expect(store.get('some_value','foo')).to be_nil
|
99
|
+
end
|
100
|
+
end
|
101
|
+
describe '.delete' do
|
102
|
+
it { expect(store.delete('something','foo')).to be_nil }
|
103
|
+
it { expect(store.delete('something')).to be_empty }
|
104
|
+
it 'deletes the value of a format' do
|
105
|
+
store.set('some_value','foo','bla')
|
106
|
+
expect(store.delete('some_value','foo')).to eql('bla')
|
107
|
+
expect(store.get('some_value','foo')).to be_nil
|
108
|
+
end
|
109
|
+
it 'deletes only the value of a format' do
|
110
|
+
store.set('some_value','plain','value')
|
111
|
+
store.set('some_value','foo','bla')
|
112
|
+
expect(store.delete('some_value','plain')).to eql('value')
|
113
|
+
expect(store.get('some_value','plain')).to be_nil
|
114
|
+
expect(store.get('some_value','foo')).to eql('bla')
|
115
|
+
end
|
116
|
+
it 'deletes all values without a format' do
|
117
|
+
store.set('some_value','plain','value')
|
118
|
+
store.set('some_value','foo','bla')
|
119
|
+
hash = store.delete('some_value')
|
120
|
+
expect(hash).to be_a_kind_of(Hash)
|
121
|
+
expect(hash['plain']).to eql('value')
|
122
|
+
expect(hash['foo']).to eql('bla')
|
123
|
+
expect(store.get('some_value','plain')).to be_nil
|
124
|
+
expect(store.get('some_value','foo')).to be_nil
|
125
|
+
end
|
126
|
+
end
|
127
|
+
describe 'expiration' do
|
128
|
+
it 'will not return an expired key' do
|
129
|
+
store.set('some_expiring_value','plain','to_be_expired',{ 'expires' => 2 })
|
130
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired')
|
131
|
+
sleep 3
|
132
|
+
expect(store.get('some_expiring_value','plain')).to be_nil
|
133
|
+
end
|
134
|
+
it 'increases expiration when setting anything for that key' do
|
135
|
+
store.set('some_expiring_value','plain','to_be_expired',{ 'expires' => 2 })
|
136
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired')
|
137
|
+
sleep 1
|
138
|
+
store.set('some_expiring_value','bla','bla_to_be_expired',{ 'expires' => 3 })
|
139
|
+
sleep 2
|
140
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired')
|
141
|
+
sleep 2
|
142
|
+
expect(store.get('some_expiring_value','plain')).to be_nil
|
143
|
+
end
|
144
|
+
it 'keeps expiration when setting another value' do
|
145
|
+
store.set('some_expiring_value','plain','to_be_expired',{ 'expires' => 2 })
|
146
|
+
store.set('some_expiring_value','foo','to_be_expired_foo')
|
147
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired')
|
148
|
+
sleep 3
|
149
|
+
expect(store.get('some_expiring_value','plain')).to be_nil
|
150
|
+
expect(store.get('some_expiring_value','foo')).to be_nil
|
151
|
+
end
|
152
|
+
it 'setting plain clears everything including expiration' do
|
153
|
+
store.set('some_expiring_value','plain','to_be_expired',{ 'expires' => 2 })
|
154
|
+
sleep 1
|
155
|
+
store.set('some_expiring_value','plain','to_be_expired2')
|
156
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired2')
|
157
|
+
sleep 3
|
158
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired2')
|
159
|
+
end
|
160
|
+
it 'extends expiration when setting another value' do
|
161
|
+
store.set('some_expiring_value','plain','to_be_expired',{ 'expires' => 4 })
|
162
|
+
sleep 2
|
163
|
+
store.set('some_expiring_value','foo','to_be_expired_foo')
|
164
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired')
|
165
|
+
sleep 3
|
166
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired')
|
167
|
+
sleep 2
|
168
|
+
expect(store.get('some_expiring_value','plain')).to be_nil
|
169
|
+
end
|
170
|
+
it 'extends expiration when deleting a format' do
|
171
|
+
store.set('some_expiring_value','plain','to_be_expired',{ 'expires' => 4 })
|
172
|
+
store.set('some_expiring_value','foo','to_be_expired2')
|
173
|
+
sleep 2
|
174
|
+
expect(store.delete('some_expiring_value','foo')).to eql('to_be_expired2')
|
175
|
+
sleep 3
|
176
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired')
|
177
|
+
sleep 2
|
178
|
+
expect(store.get('some_expiring_value','plain')).to be_nil
|
179
|
+
end
|
180
|
+
it 'keeps expiration although we\'re fetching a value' do
|
181
|
+
store.set('some_expiring_value','plain','to_be_expired',{ 'expires' => 3 })
|
182
|
+
sleep 2
|
183
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired')
|
184
|
+
sleep 2
|
185
|
+
expect(store.get('some_expiring_value','plain')).to be_nil
|
186
|
+
end
|
187
|
+
it 'readding a value with an expiration makes it expiring in the future' do
|
188
|
+
store.set('some_expiring_value','plain','to_be_expired')
|
189
|
+
store.set('some_expiring_value','plain','to_be_expired2',{ 'expires' => 2 })
|
190
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired2')
|
191
|
+
sleep 3
|
192
|
+
expect(store.get('some_expiring_value','plain')).to be_nil
|
193
|
+
end
|
194
|
+
it 'setting an expires of false removes expiration' do
|
195
|
+
store.set('some_expiring_value','plain','to_be_expired2',{ 'expires' => 2 })
|
196
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired2')
|
197
|
+
store.set('some_expiring_value','plain','to_be_expired',{ 'expires' => false })
|
198
|
+
sleep 3
|
199
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired')
|
200
|
+
end
|
201
|
+
it 'setting an expires of 0 removes expiration' do
|
202
|
+
store.set('some_expiring_value','plain','to_be_expired2',{ 'expires' => 2 })
|
203
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired2')
|
204
|
+
store.set('some_expiring_value','plain','to_be_expired',{ 'expires' => 0 })
|
205
|
+
sleep 3
|
206
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired')
|
207
|
+
end
|
208
|
+
it 'setting an expires of false removes expiration even if it\'s for a different format' do
|
209
|
+
store.set('some_expiring_value','plain','to_be_expired2',{ 'expires' => 2 })
|
210
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired2')
|
211
|
+
store.set('some_expiring_value','foo','to_be_expired_foo',{ 'expires' => false })
|
212
|
+
sleep 3
|
213
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired2')
|
214
|
+
expect(store.get('some_expiring_value','foo')).to eql('to_be_expired_foo')
|
215
|
+
end
|
216
|
+
it 'setting an expires of 0 removes expiration even if it\'s for a different format' do
|
217
|
+
store.set('some_expiring_value','plain','to_be_expired2',{ 'expires' => 2 })
|
218
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired2')
|
219
|
+
store.set('some_expiring_value','foo','to_be_expired_foo',{ 'expires' => 0 })
|
220
|
+
sleep 3
|
221
|
+
expect(store.get('some_expiring_value','plain')).to eql('to_be_expired2')
|
222
|
+
expect(store.get('some_expiring_value','foo')).to eql('to_be_expired_foo')
|
223
|
+
end
|
224
|
+
end
|
14
225
|
end
|
15
226
|
|
16
227
|
def default_config
|
@@ -18,26 +229,30 @@ def default_config
|
|
18
229
|
end
|
19
230
|
|
20
231
|
def test_config
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
232
|
+
@config ||= default_config.merge({
|
233
|
+
'store' => :memory,
|
234
|
+
})
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_config_persistent
|
238
|
+
@config ||= default_config.merge({
|
239
|
+
'store_options' => {
|
240
|
+
'adapter' => :YAML,
|
241
|
+
'adapter_options' => {
|
242
|
+
:file => trocla_yaml_file
|
243
|
+
},
|
244
|
+
},
|
245
|
+
})
|
26
246
|
end
|
27
247
|
|
28
248
|
def ssl_test_config
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
}
|
36
|
-
@ssl_config['adapter'] = :YAML
|
37
|
-
@ssl_config['adapter_options'] = {
|
38
|
-
:file => trocla_yaml_file
|
39
|
-
}
|
40
|
-
@ssl_config
|
249
|
+
@ssl_config ||= test_config_persistent.merge({
|
250
|
+
'encryption' => :ssl,
|
251
|
+
'encryption_options' => {
|
252
|
+
:private_key => data_dir('trocla.key'),
|
253
|
+
:public_key => data_dir('trocla.pub'),
|
254
|
+
},
|
255
|
+
})
|
41
256
|
end
|
42
257
|
|
43
258
|
def base_dir
|