handle-system 0.0.3
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/Gemfile +5 -0
- data/LICENSE.txt +34 -0
- data/README.md +57 -0
- data/Rakefile +28 -0
- data/lib/handle/command/connection.rb +134 -0
- data/lib/handle/command/persistence.rb +57 -0
- data/lib/handle/command.rb +2 -0
- data/lib/handle/field/admin.rb +79 -0
- data/lib/handle/field.rb +125 -0
- data/lib/handle/java/connection.rb +95 -0
- data/lib/handle/java/persistence.rb +54 -0
- data/lib/handle/java.rb +18 -0
- data/lib/handle/permissions.rb +61 -0
- data/lib/handle/record.rb +82 -0
- data/lib/handle/version.rb +3 -0
- data/lib/handle.rb +19 -0
- data/spec/admin_spec.rb +48 -0
- data/spec/command/connection_spec.rb +145 -0
- data/spec/command/persistence_spec.rb +63 -0
- data/spec/field_spec.rb +40 -0
- data/spec/java/connection_spec.rb +118 -0
- data/spec/java/persistence_spec.rb +67 -0
- data/spec/permissions_spec.rb +39 -0
- data/spec/record_spec.rb +72 -0
- data/spec/spec_helper.rb +20 -0
- metadata +136 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
module Handle
|
2
|
+
class Permissions
|
3
|
+
attr :bitmask
|
4
|
+
|
5
|
+
def initialize(*flags)
|
6
|
+
if flags.last.is_a?(Fixnum)
|
7
|
+
@bitmask = flags.pop
|
8
|
+
else
|
9
|
+
@bitmask = 0
|
10
|
+
end
|
11
|
+
@flags = Hash[flags.reverse.collect.with_index { |f,i| [f,2**i] }.reverse]
|
12
|
+
end
|
13
|
+
|
14
|
+
def bitmask=(value)
|
15
|
+
@bitmask = value.to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(sym, *args)
|
19
|
+
flag = sym.to_s.sub(/([\?\=])$/,'').to_sym
|
20
|
+
if @flags.include?(flag)
|
21
|
+
case $1
|
22
|
+
when '?' then read(flag)
|
23
|
+
when '=' then write(flag,args.first)
|
24
|
+
else super(sym, *args)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
super(sym, *args)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_bool
|
32
|
+
@flags.keys.collect { |flag| read(flag) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
"%#{@flags.length}.#{@flags.length}b" % bitmask
|
37
|
+
end
|
38
|
+
|
39
|
+
def max
|
40
|
+
2**@flags.length-1
|
41
|
+
end
|
42
|
+
|
43
|
+
def read(flag)
|
44
|
+
self.bitmask & @flags[flag] > 0
|
45
|
+
end
|
46
|
+
|
47
|
+
def write(flag, value)
|
48
|
+
mask = @flags[flag]
|
49
|
+
if value
|
50
|
+
self.bitmask |= mask
|
51
|
+
else
|
52
|
+
self.bitmask &= (max - mask)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def inspect
|
57
|
+
str = @flags.keys.select { |flag| self.read(flag) }.collect { |flag| flag.inspect }.join(', ')
|
58
|
+
"[#{str}]"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Handle
|
2
|
+
class Record
|
3
|
+
attr :fields
|
4
|
+
|
5
|
+
def self.from_data(data)
|
6
|
+
result = self.new
|
7
|
+
if data.is_a?(String)
|
8
|
+
data.lines.each { |line| result << Handle::Field::Base.from_data(line) }
|
9
|
+
else
|
10
|
+
data.each { |field| result << Handle::Field::Base.from_data(field) }
|
11
|
+
end
|
12
|
+
result
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(fields=[])
|
16
|
+
initialize_with(fields)
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize_with(fields)
|
20
|
+
@fields = fields
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_a
|
24
|
+
@fields
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_json *args
|
28
|
+
to_a.to_json *args
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
fields.collect(&:to_s).join("\n")
|
33
|
+
end
|
34
|
+
|
35
|
+
def <<(field)
|
36
|
+
fields << field if field.kind_of?(Handle::Field::Base)
|
37
|
+
end
|
38
|
+
|
39
|
+
def add(field_type, value=nil)
|
40
|
+
field = Handle::Field.const_get(field_type).new
|
41
|
+
indexed_fields = fields.select { |f| f.index < 100 }.sort { |a,b| b.index <=> a.index }
|
42
|
+
if indexed_fields.empty?
|
43
|
+
field.index = 1
|
44
|
+
else
|
45
|
+
field.index = indexed_fields.first.index + 1
|
46
|
+
end
|
47
|
+
field.value = value
|
48
|
+
fields << field
|
49
|
+
field
|
50
|
+
end
|
51
|
+
|
52
|
+
def find_by_index(index)
|
53
|
+
self.find { |field| field.index == index }
|
54
|
+
end
|
55
|
+
|
56
|
+
def |(other)
|
57
|
+
result = { add: Record.new, update: Record.new, delete: Record.new }
|
58
|
+
my_ixs = self.collect(&:index).sort
|
59
|
+
other.each do |field|
|
60
|
+
if my_ixs.delete(field.index)
|
61
|
+
result[:update] << field
|
62
|
+
else
|
63
|
+
result[:add] << field
|
64
|
+
end
|
65
|
+
end
|
66
|
+
my_ixs.each { |ix| result[:delete] << self.find_by_index(ix) }
|
67
|
+
result
|
68
|
+
end
|
69
|
+
|
70
|
+
def ==(other)
|
71
|
+
self.to_a == other.to_a
|
72
|
+
end
|
73
|
+
|
74
|
+
def method_missing(sym, *args, &block)
|
75
|
+
if @fields.respond_to?(sym)
|
76
|
+
@fields.send(sym, *args, &block)
|
77
|
+
else
|
78
|
+
super
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/handle.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "handle/permissions"
|
2
|
+
require "handle/record"
|
3
|
+
require "handle/field"
|
4
|
+
require "handle/field/admin"
|
5
|
+
|
6
|
+
module Handle
|
7
|
+
persistence_module = Module.const_defined?('JRuby') ? 'java' : 'command'
|
8
|
+
require "handle/#{persistence_module}"
|
9
|
+
Record.send(:include, Handle::Persistence)
|
10
|
+
class HandleError < Exception
|
11
|
+
def initialize msg=nil
|
12
|
+
unless msg.nil?
|
13
|
+
msg = msg[0] + msg[1..-1].downcase
|
14
|
+
end
|
15
|
+
super msg
|
16
|
+
end
|
17
|
+
end
|
18
|
+
class NotFound < HandleError; end
|
19
|
+
end
|
data/spec/admin_spec.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../spec_helper',__FILE__)
|
2
|
+
|
3
|
+
describe Handle::Field::HSAdmin do
|
4
|
+
let(:handle_str) { Handle::Field::Base.from_data(' index=100 ttl=15200 type=HS_ADMIN rwr- "0FFF0000000D302E4E412F46414B452E41444D494E0000012C"') }
|
5
|
+
let(:handle_hash) { Handle::Field::Base.from_data({ index: 100, ttl: 15200, type: 'HS_ADMIN', perms: 14, value: '0FFF0000000D302E4E412F46414B452E41444D494E0000012C' }) }
|
6
|
+
|
7
|
+
it "#from_hash" do
|
8
|
+
handle = handle_hash
|
9
|
+
expect(handle).to be_a(Handle::Field::HSAdmin)
|
10
|
+
expect(handle.class.value_type).to eq('HS_ADMIN')
|
11
|
+
expect(handle.ttl).to eq(15200)
|
12
|
+
expect(handle.admin_handle).to eq('0.NA/FAKE.ADMIN')
|
13
|
+
expect(handle.admin_index).to eq(300)
|
14
|
+
expect(handle.admin_perms.bitmask).to eq(4095)
|
15
|
+
# expect(handle.value).to eq('http://www.example.edu/fake-handle')
|
16
|
+
expect(handle.value_str).to eq('300:111111111111:0.NA/FAKE.ADMIN')
|
17
|
+
end
|
18
|
+
|
19
|
+
it "#from_string" do
|
20
|
+
handle = handle_str
|
21
|
+
expect(handle).to be_a(Handle::Field::HSAdmin)
|
22
|
+
expect(handle.class.value_type).to eq('HS_ADMIN')
|
23
|
+
expect(handle.ttl).to eq(15200)
|
24
|
+
expect(handle.admin_handle).to eq('0.NA/FAKE.ADMIN')
|
25
|
+
expect(handle.admin_index).to eq(300)
|
26
|
+
expect(handle.admin_perms.bitmask).to eq(4095)
|
27
|
+
# expect(handle.value).to eq('http://www.example.edu/fake-handle')
|
28
|
+
expect(handle.value_str).to eq('300:111111111111:0.NA/FAKE.ADMIN')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "#to_hash" do
|
32
|
+
h = handle_str.to_h
|
33
|
+
expect(h).to be_a(Hash)
|
34
|
+
expect(h).to eq({
|
35
|
+
index: 100,
|
36
|
+
type: 'HS_ADMIN',
|
37
|
+
ttl: 15200,
|
38
|
+
perms: 14,
|
39
|
+
admin_handle: '0.NA/FAKE.ADMIN',
|
40
|
+
admin_index: 300,
|
41
|
+
admin_perms: 4095
|
42
|
+
})
|
43
|
+
end
|
44
|
+
|
45
|
+
it "#to_s" do
|
46
|
+
expect(handle_hash.to_s).to eq(handle_str.to_s)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require File.expand_path('../../spec_helper',__FILE__)
|
2
|
+
|
3
|
+
on_cruby do
|
4
|
+
def parse_batch(command)
|
5
|
+
(cmd, fname, redirect) = command.split(/\s+/,3)
|
6
|
+
File.read(fname).split(/\n\n/).collect { |batch|
|
7
|
+
(op, data) = batch.split(/\n/,2)
|
8
|
+
{ :op => op.strip, :data => data.strip }
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
describe Handle::Command::Connection do
|
13
|
+
describe "#initialize" do
|
14
|
+
it "file-based private key" do
|
15
|
+
Handle::Command::Connection.new('0.NA/FAKE.ADMIN', 300, 'privkey', 'keypass').batch { |b|
|
16
|
+
b.should_receive(:`) do |command|
|
17
|
+
expect(parse_batch(command)[0]).to eq({ op: "AUTHENTICATE PUBKEY:300:0.NA/FAKE.ADMIN", data: "privkey|keypass" })
|
18
|
+
""
|
19
|
+
end
|
20
|
+
}.should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "shared secret" do
|
24
|
+
Handle::Command::Connection.new('0.NA/FAKE.ADMIN', 301, 'seckey') { |b|
|
25
|
+
b.should_receive(:`) do |command|
|
26
|
+
expect(parse_batch(command)[0]).to eq({ op: "AUTHENTICATE SECKEY:301:0.NA/FAKE.ADMIN", data: "seckey" })
|
27
|
+
""
|
28
|
+
end
|
29
|
+
}.should be_true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "handle manipulation" do
|
34
|
+
let(:fake_handle) { 'FAKE.PREFIX/FAKE.HANDLE' }
|
35
|
+
let(:new_handle) { 'FAKE.PREFIX/NEW.HANDLE' }
|
36
|
+
let(:bad_handle) { 'FAKE.PREFIX/NEW.HANDLE' }
|
37
|
+
|
38
|
+
let(:record) {
|
39
|
+
record = Handle::Record.new
|
40
|
+
record.add(:URL, 'http://www.example.edu/fake-handle').index = 2
|
41
|
+
record.add(:Email, 'handle@example.edu').index = 6
|
42
|
+
record << Handle::Field::HSAdmin.new('0.NA/FAKE.ADMIN')
|
43
|
+
record
|
44
|
+
}
|
45
|
+
let(:server) { double(Handle::Java::Native::HSAdapter) }
|
46
|
+
subject { Handle::Command::Connection.new('0.NA/FAKE.ADMIN', 300, 'privkey', 'keypass') }
|
47
|
+
|
48
|
+
it "#resolve_handle" do
|
49
|
+
subject.should_receive(:`) { |command|
|
50
|
+
expect(command).to match(/hdl-qresolver #{fake_handle}/)
|
51
|
+
"Got Response:\n#{record.to_s}"
|
52
|
+
}
|
53
|
+
expect(subject.resolve_handle(fake_handle)).to eq(record)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "#resolve_handle (not found)" do
|
57
|
+
subject.should_receive(:`) { |command|
|
58
|
+
expect(command).to match(/hdl-qresolver #{bad_handle}/)
|
59
|
+
"Got Error:\nError(100): HANDLE NOT FOUND"
|
60
|
+
}
|
61
|
+
expect { subject.resolve_handle(bad_handle) }.to raise_error(Handle::NotFound)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "#resolve_handle (other error)" do
|
65
|
+
subject.should_receive(:`) { |command|
|
66
|
+
expect(command).to match(/hdl-qresolver #{bad_handle}/)
|
67
|
+
"Got Error:\nError(3): SERVER TOO BUSY"
|
68
|
+
}
|
69
|
+
expect { subject.resolve_handle(bad_handle) }.to raise_error(Handle::HandleError)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "#create_record" do
|
73
|
+
new_record = subject.create_record(new_handle)
|
74
|
+
expect(new_record.connection).to eq(subject)
|
75
|
+
expect(new_record.handle).to eq(new_handle)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "#create_handle" do
|
79
|
+
Handle::Command::Batch.any_instance.should_receive(:`) do |command|
|
80
|
+
ops = parse_batch(command)
|
81
|
+
expect(ops.length).to eq(2)
|
82
|
+
expect(ops[1][:op]).to eq("CREATE #{new_handle}")
|
83
|
+
expect(ops[1][:data]).to eq("2 URL 86400 1110 UTF8 http://www.example.edu/fake-handle\n6 EMAIL 86400 1110 UTF8 handle@example.edu\n100 HS_ADMIN 86400 1110 ADMIN 300:111111111111:0.NA/FAKE.ADMIN")
|
84
|
+
"==>SUCCESS[7]: create:#{new_handle}"
|
85
|
+
end
|
86
|
+
expect(subject.create_handle(new_handle, record)).to be_true
|
87
|
+
end
|
88
|
+
|
89
|
+
it "#create_handle (handle already exists)" do
|
90
|
+
Handle::Command::Batch.any_instance.should_receive(:`) do |command|
|
91
|
+
ops = parse_batch(command)
|
92
|
+
expect(ops.length).to eq(2)
|
93
|
+
expect(ops[1][:op]).to eq("CREATE #{new_handle}")
|
94
|
+
expect(ops[1][:data]).to eq("2 URL 86400 1110 UTF8 http://www.example.edu/fake-handle\n6 EMAIL 86400 1110 UTF8 handle@example.edu\n100 HS_ADMIN 86400 1110 ADMIN 300:111111111111:0.NA/FAKE.ADMIN")
|
95
|
+
"==>FAILURE[7]: create:#{new_handle}: Error(101): HANDLE ALREADY EXISTS"
|
96
|
+
end
|
97
|
+
expect { subject.create_handle(new_handle, record) }.to raise_error(Handle::HandleError)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "#add_handle_values" do
|
101
|
+
Handle::Command::Batch.any_instance.should_receive(:`) do |command|
|
102
|
+
ops = parse_batch(command)
|
103
|
+
expect(ops.length).to eq(2)
|
104
|
+
expect(ops[1][:op]).to eq("ADD #{new_handle}")
|
105
|
+
expect(ops[1][:data]).to eq("2 URL 86400 1110 UTF8 http://www.example.edu/fake-handle\n6 EMAIL 86400 1110 UTF8 handle@example.edu\n100 HS_ADMIN 86400 1110 ADMIN 300:111111111111:0.NA/FAKE.ADMIN")
|
106
|
+
"==>SUCCESS[7]: add values:#{new_handle}"
|
107
|
+
end
|
108
|
+
expect(subject.add_handle_values(new_handle, record)).to be_true
|
109
|
+
end
|
110
|
+
|
111
|
+
it "#update_handle_values" do
|
112
|
+
Handle::Command::Batch.any_instance.should_receive(:`) do |command|
|
113
|
+
ops = parse_batch(command)
|
114
|
+
expect(ops.length).to eq(2)
|
115
|
+
expect(ops[1][:op]).to eq("MODIFY #{new_handle}")
|
116
|
+
expect(ops[1][:data]).to eq("2 URL 86400 1110 UTF8 http://www.example.edu/fake-handle\n6 EMAIL 86400 1110 UTF8 handle@example.edu\n100 HS_ADMIN 86400 1110 ADMIN 300:111111111111:0.NA/FAKE.ADMIN")
|
117
|
+
"==>SUCCESS[7]: modify values:#{new_handle}"
|
118
|
+
end
|
119
|
+
expect(subject.update_handle_values(new_handle, record)).to be_true
|
120
|
+
end
|
121
|
+
|
122
|
+
it "#delete_handle_values" do
|
123
|
+
Handle::Command::Batch.any_instance.should_receive(:`) do |command|
|
124
|
+
ops = parse_batch(command)
|
125
|
+
expect(ops.length).to eq(2)
|
126
|
+
expect(ops[1][:op]).to eq("REMOVE 2,6,100:#{new_handle}")
|
127
|
+
expect(ops[1][:data]).to be_empty
|
128
|
+
"==>SUCCESS[4]: delete values:#{new_handle}"
|
129
|
+
end
|
130
|
+
expect(subject.delete_handle_values(new_handle, record)).to be_true
|
131
|
+
end
|
132
|
+
|
133
|
+
it "#delete_handle" do
|
134
|
+
Handle::Command::Batch.any_instance.should_receive(:`) do |command|
|
135
|
+
ops = parse_batch(command)
|
136
|
+
expect(ops.length).to eq(2)
|
137
|
+
expect(ops[1][:op]).to eq("DELETE #{new_handle}")
|
138
|
+
expect(ops[1][:data]).to be_empty
|
139
|
+
"==>SUCCESS[7]: delete:#{new_handle}"
|
140
|
+
end
|
141
|
+
expect(subject.delete_handle(new_handle)).to be_true
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require File.expand_path('../../spec_helper',__FILE__)
|
2
|
+
|
3
|
+
on_cruby do
|
4
|
+
describe Handle::Command::Persistence do
|
5
|
+
let(:fake_handle) { 'FAKE.PREFIX/FAKE.HANDLE' }
|
6
|
+
let(:connection) { double(Handle::Command::Connection) }
|
7
|
+
let(:record) {
|
8
|
+
record = Handle::Record.new
|
9
|
+
record.add(:URL, 'http://www.example.edu/fake-handle').index = 2
|
10
|
+
record.add(:Email, 'handle@example.edu').index = 6
|
11
|
+
record << Handle::Field::HSAdmin.new('0.NA/FAKE.ADMIN')
|
12
|
+
record.connection = connection
|
13
|
+
record
|
14
|
+
}
|
15
|
+
subject { record }
|
16
|
+
|
17
|
+
it "#reload" do
|
18
|
+
current = subject.to_s
|
19
|
+
subject.handle = fake_handle
|
20
|
+
connection.should_receive(:resolve_handle).with(fake_handle) { Handle::Record.from_data(subject.to_s) }
|
21
|
+
subject.reload
|
22
|
+
expect(subject.to_s).to eq(current)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "#destroy" do
|
26
|
+
subject.handle = fake_handle
|
27
|
+
connection.should_receive(:delete_handle).with(fake_handle)
|
28
|
+
subject.destroy
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#save" do
|
32
|
+
it "nil handle, no param" do
|
33
|
+
expect { subject.save }.to raise_error(Handle::HandleError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "nil handle, param" do
|
37
|
+
connection.should_receive(:create_handle).with(fake_handle, subject) { true }
|
38
|
+
expect(subject.save(fake_handle)).to be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "existing handle, no existing record" do
|
42
|
+
subject.handle = fake_handle
|
43
|
+
current = subject.to_s
|
44
|
+
connection.should_receive(:resolve_handle).with(fake_handle) { raise Handle::NotFound.new('Handle not found') }
|
45
|
+
connection.should_receive(:create_handle) { |handle, record| expect(record).to eq(subject) }
|
46
|
+
subject.save
|
47
|
+
end
|
48
|
+
|
49
|
+
it "change existing record" do
|
50
|
+
subject.handle = fake_handle
|
51
|
+
current = subject.to_s
|
52
|
+
connection.should_receive(:resolve_handle).with(fake_handle) { Handle::Record.from_data(current) }
|
53
|
+
subject.delete(subject.find_by_index(6))
|
54
|
+
subject.add(:URN, 'info:example:fake-handle')
|
55
|
+
connection.should_receive(:delete_handle_values) { |handle, record| expect(record.length).to eq(1) }
|
56
|
+
connection.should_receive(:add_handle_values) { |handle, record| expect(record.length).to eq(1) }
|
57
|
+
connection.should_receive(:update_handle_values) { |handle, record| expect(record.length).to eq(2) }
|
58
|
+
subject.save
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
data/spec/field_spec.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path('../spec_helper',__FILE__)
|
2
|
+
|
3
|
+
describe Handle::Field do
|
4
|
+
let(:handle_str) { Handle::Field::Base.from_data(' index=2 ttl=15200 type=URL rwr- "http://www.example.edu/fake-handle"') }
|
5
|
+
let(:handle_hash) { Handle::Field::Base.from_data({ index: 2, ttl: 15200, type: 'URL', perms: 14, value: 'http://www.example.edu/fake-handle' }) }
|
6
|
+
|
7
|
+
it "#from_hash" do
|
8
|
+
handle = handle_hash
|
9
|
+
expect(handle).to be_a(Handle::Field::URL)
|
10
|
+
expect(handle.class.value_type).to eq('URL')
|
11
|
+
expect(handle.ttl).to eq(15200)
|
12
|
+
expect(handle.value).to eq('http://www.example.edu/fake-handle')
|
13
|
+
expect(handle.value_str).to eq('http://www.example.edu/fake-handle')
|
14
|
+
end
|
15
|
+
|
16
|
+
it "#from_string" do
|
17
|
+
handle = handle_str
|
18
|
+
expect(handle).to be_a(Handle::Field::URL)
|
19
|
+
expect(handle.class.value_type).to eq('URL')
|
20
|
+
expect(handle.ttl).to eq(15200)
|
21
|
+
expect(handle.value).to eq('http://www.example.edu/fake-handle')
|
22
|
+
expect(handle.value_str).to eq('http://www.example.edu/fake-handle')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "#to_hash" do
|
26
|
+
h = handle_str.to_h
|
27
|
+
expect(h).to be_a(Hash)
|
28
|
+
expect(h).to eq({
|
29
|
+
index: 2,
|
30
|
+
type: 'URL',
|
31
|
+
ttl: 15200,
|
32
|
+
perms: 14,
|
33
|
+
value: 'http://www.example.edu/fake-handle'
|
34
|
+
})
|
35
|
+
end
|
36
|
+
|
37
|
+
it "#to_s" do
|
38
|
+
expect(handle_hash.to_s).to eq(handle_str.to_s)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require File.expand_path('../../spec_helper',__FILE__)
|
2
|
+
|
3
|
+
on_jruby do
|
4
|
+
describe Handle::Java::Connection do
|
5
|
+
describe "#initialize" do
|
6
|
+
it "file-based private key" do
|
7
|
+
File.should_receive(:exists?).with('privkey') { true }
|
8
|
+
File.should_receive(:read).with('privkey') { 'privkey_content' }
|
9
|
+
Handle::Java::Native::HSAdapterFactory.should_receive(:new_instance) do |handle, index, key, secret|
|
10
|
+
expect(handle).to eq('0.NA/FAKE.ADMIN')
|
11
|
+
expect(index).to eq(300)
|
12
|
+
expect(secret.collect(&:chr).join).to eq('keypass')
|
13
|
+
expect(key.collect(&:chr).join).to eq('privkey_content')
|
14
|
+
end
|
15
|
+
Handle::Java::Connection.new('0.NA/FAKE.ADMIN', 300, 'privkey', 'keypass')
|
16
|
+
end
|
17
|
+
|
18
|
+
it "literal private key" do
|
19
|
+
File.should_receive(:exists?).with('privkey') { false }
|
20
|
+
File.should_not_receive(:read)
|
21
|
+
Handle::Java::Native::HSAdapterFactory.should_receive(:new_instance) do |handle, index, key, secret|
|
22
|
+
expect(handle).to eq('0.NA/FAKE.ADMIN')
|
23
|
+
expect(index).to eq(300)
|
24
|
+
expect(secret.collect(&:chr).join).to eq('keypass')
|
25
|
+
expect(key.collect(&:chr).join).to eq('privkey')
|
26
|
+
end
|
27
|
+
Handle::Java::Connection.new('0.NA/FAKE.ADMIN', 300, 'privkey', 'keypass')
|
28
|
+
end
|
29
|
+
|
30
|
+
it "shared secret" do
|
31
|
+
File.should_not_receive(:exists?)
|
32
|
+
File.should_not_receive(:read)
|
33
|
+
Handle::Java::Native::HSAdapterFactory.should_receive(:new_instance) do |handle, index, key|
|
34
|
+
expect(handle).to eq('0.NA/FAKE.ADMIN')
|
35
|
+
expect(index).to eq(301)
|
36
|
+
expect(key.collect(&:chr).join).to eq('seckey')
|
37
|
+
end
|
38
|
+
Handle::Java::Connection.new('0.NA/FAKE.ADMIN', 301, 'seckey')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "handle manipulation" do
|
43
|
+
let(:fake_handle) { 'FAKE.PREFIX/FAKE.HANDLE' }
|
44
|
+
let(:new_handle) { 'FAKE.PREFIX/NEW.HANDLE' }
|
45
|
+
let(:bad_handle) { 'FAKE.PREFIX/NEW.HANDLE' }
|
46
|
+
|
47
|
+
let(:record) {
|
48
|
+
record = Handle::Record.new
|
49
|
+
record.add(:URL, 'http://www.example.edu/fake-handle').index = 2
|
50
|
+
record.add(:Email, 'handle@example.edu').index = 6
|
51
|
+
record << Handle::Field::HSAdmin.new('0.NA/FAKE.ADMIN')
|
52
|
+
record
|
53
|
+
}
|
54
|
+
let(:server) { double(Handle::Java::Native::HSAdapter) }
|
55
|
+
subject { Handle::Java::Connection.new('0.NA/FAKE.ADMIN', 300, 'privkey', 'keypass') }
|
56
|
+
|
57
|
+
before(:each) do
|
58
|
+
Handle::Java::Native::HSAdapterFactory.stub(:new_instance) { server }
|
59
|
+
Handle::Java::Native::HSAdapterFactory.stub(:newInstance) { server }
|
60
|
+
end
|
61
|
+
|
62
|
+
it "#native" do
|
63
|
+
expect(subject.native).to eq(server)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "#use_udp" do
|
67
|
+
server.should_receive(:setUseUDP).with(false)
|
68
|
+
subject.use_udp = false
|
69
|
+
end
|
70
|
+
|
71
|
+
it "#resolve_handle" do
|
72
|
+
server.should_receive(:resolveHandle).with(fake_handle, anything(), anything(), anything()) { record.to_s }
|
73
|
+
expect(subject.resolve_handle(fake_handle)).to eq(record)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "#resolve_handle (not found)" do
|
77
|
+
server.should_receive(:resolveHandle).with(bad_handle, anything(), anything(), anything()) { raise Handle::Java::Native::HandleException.new(9, "Handle not found") }
|
78
|
+
expect { subject.resolve_handle(bad_handle) }.to raise_error(Handle::NotFound)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "#resolve_handle (other error)" do
|
82
|
+
server.should_receive(:resolveHandle).with(bad_handle, anything(), anything(), anything()) { raise Handle::Java::Native::HandleException.new(2, "Service not found") }
|
83
|
+
expect { subject.resolve_handle(bad_handle) }.to raise_error(Handle::HandleError)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "#create_record" do
|
87
|
+
new_record = subject.create_record(new_handle)
|
88
|
+
expect(new_record.connection).to eq(subject)
|
89
|
+
expect(new_record.handle).to eq(new_handle)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "#create_handle" do
|
93
|
+
server.should_receive(:createHandle).with(new_handle, anything()) { true }
|
94
|
+
expect(subject.create_handle(new_handle, record)).to be_true
|
95
|
+
end
|
96
|
+
|
97
|
+
it "#add_handle_values" do
|
98
|
+
server.should_receive(:addHandleValues).with(new_handle, anything()) { true }
|
99
|
+
expect(subject.add_handle_values(new_handle, record)).to be_true
|
100
|
+
end
|
101
|
+
|
102
|
+
it "#update_handle_values" do
|
103
|
+
server.should_receive(:updateHandleValues).with(new_handle, anything()) { true }
|
104
|
+
expect(subject.update_handle_values(new_handle, record)).to be_true
|
105
|
+
end
|
106
|
+
|
107
|
+
it "#delete_handle_values" do
|
108
|
+
server.should_receive(:deleteHandleValues).with(new_handle, anything()) { true }
|
109
|
+
expect(subject.delete_handle_values(new_handle, record)).to be_true
|
110
|
+
end
|
111
|
+
|
112
|
+
it "#delete_handle" do
|
113
|
+
server.should_receive(:deleteHandle).with(new_handle) { true }
|
114
|
+
expect(subject.delete_handle(new_handle)).to be_true
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.expand_path('../../spec_helper',__FILE__)
|
2
|
+
|
3
|
+
on_jruby do
|
4
|
+
describe Handle::Java::Persistence do
|
5
|
+
let(:fake_handle) { 'FAKE.PREFIX/FAKE.HANDLE' }
|
6
|
+
let(:connection) { double(Handle::Java::Connection) }
|
7
|
+
let(:record) {
|
8
|
+
record = Handle::Record.new
|
9
|
+
record.add(:URL, 'http://www.example.edu/fake-handle').index = 2
|
10
|
+
record.add(:Email, 'handle@example.edu').index = 6
|
11
|
+
record << Handle::Field::HSAdmin.new('0.NA/FAKE.ADMIN')
|
12
|
+
record.connection = connection
|
13
|
+
record
|
14
|
+
}
|
15
|
+
subject { record }
|
16
|
+
|
17
|
+
it "#to_java" do
|
18
|
+
expect(Handle::Record.from_data(subject.to_java)).to eq(subject)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "#reload" do
|
22
|
+
current = subject.to_s
|
23
|
+
subject.handle = fake_handle
|
24
|
+
connection.should_receive(:resolve_handle).with(fake_handle) { Handle::Record.from_data(subject.to_s) }
|
25
|
+
subject.reload
|
26
|
+
expect(subject.to_s).to eq(current)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "#destroy" do
|
30
|
+
subject.handle = fake_handle
|
31
|
+
connection.should_receive(:delete_handle).with(fake_handle)
|
32
|
+
subject.destroy
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#save" do
|
36
|
+
it "nil handle, no param" do
|
37
|
+
expect { subject.save }.to raise_error(Handle::HandleError)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "nil handle, param" do
|
41
|
+
connection.should_receive(:create_handle).with(fake_handle, subject) { true }
|
42
|
+
expect(subject.save(fake_handle)).to be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
it "existing handle, no existing record" do
|
46
|
+
subject.handle = fake_handle
|
47
|
+
current = subject.to_s
|
48
|
+
connection.should_receive(:resolve_handle).with(fake_handle) { raise Handle::NotFound.new('Handle not found') }
|
49
|
+
connection.should_receive(:create_handle) { |handle, record| expect(record).to eq(subject) }
|
50
|
+
subject.save
|
51
|
+
end
|
52
|
+
|
53
|
+
it "change existing record" do
|
54
|
+
subject.handle = fake_handle
|
55
|
+
current = subject.to_s
|
56
|
+
connection.should_receive(:resolve_handle).with(fake_handle) { Handle::Record.from_data(current) }
|
57
|
+
subject.delete(subject.find_by_index(6))
|
58
|
+
subject.add(:URN, 'info:example:fake-handle')
|
59
|
+
connection.should_receive(:delete_handle_values) { |handle, record| expect(record.length).to eq(1) }
|
60
|
+
connection.should_receive(:add_handle_values) { |handle, record| expect(record.length).to eq(1) }
|
61
|
+
connection.should_receive(:update_handle_values) { |handle, record| expect(record.length).to eq(2) }
|
62
|
+
subject.save
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|