stormpath-sdk 0.4.0 → 1.0.0.beta
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 +6 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +27 -0
- data/CHANGES.md +21 -1
- data/Gemfile +1 -2
- data/README.md +457 -11
- data/Rakefile +15 -1
- data/lib/stormpath-sdk.rb +52 -33
- data/lib/stormpath-sdk/{resource/group_list.rb → api_key.rb} +5 -9
- data/lib/stormpath-sdk/auth/authentication_result.rb +3 -13
- data/lib/stormpath-sdk/auth/basic_authenticator.rb +5 -11
- data/lib/stormpath-sdk/auth/basic_login_attempt.rb +6 -8
- data/lib/stormpath-sdk/auth/username_password_request.rb +2 -5
- data/lib/stormpath-sdk/cache/cache.rb +54 -0
- data/lib/stormpath-sdk/cache/cache_entry.rb +33 -0
- data/lib/stormpath-sdk/cache/cache_manager.rb +22 -0
- data/lib/stormpath-sdk/cache/cache_stats.rb +35 -0
- data/lib/stormpath-sdk/cache/memory_store.rb +29 -0
- data/lib/stormpath-sdk/cache/redis_store.rb +32 -0
- data/lib/stormpath-sdk/client.rb +111 -0
- data/lib/stormpath-sdk/data_store.rb +241 -0
- data/lib/stormpath-sdk/{client/api_key.rb → error.rb} +16 -10
- data/lib/stormpath-sdk/{util → ext}/hash.rb +1 -2
- data/lib/stormpath-sdk/http/authc/sauthc1_signer.rb +8 -4
- data/lib/stormpath-sdk/http/http_client_request_executor.rb +8 -7
- data/lib/stormpath-sdk/http/request.rb +4 -8
- data/lib/stormpath-sdk/{util/request_utils.rb → http/utils.rb} +17 -38
- data/lib/stormpath-sdk/resource/account.rb +12 -108
- data/lib/stormpath-sdk/resource/application.rb +35 -171
- data/lib/stormpath-sdk/resource/associations.rb +97 -0
- data/lib/stormpath-sdk/resource/base.rb +256 -0
- data/lib/stormpath-sdk/resource/collection.rb +94 -0
- data/lib/stormpath-sdk/resource/directory.rb +11 -68
- data/lib/stormpath-sdk/resource/email_verification_token.rb +3 -9
- data/lib/stormpath-sdk/resource/error.rb +4 -38
- data/lib/stormpath-sdk/resource/expansion.rb +28 -0
- data/lib/stormpath-sdk/resource/group.rb +8 -66
- data/lib/stormpath-sdk/resource/group_membership.rb +4 -55
- data/lib/stormpath-sdk/resource/{application_list.rb → instance.rb} +7 -13
- data/lib/stormpath-sdk/resource/password_reset_token.rb +5 -23
- data/lib/stormpath-sdk/resource/status.rb +22 -28
- data/lib/stormpath-sdk/resource/tenant.rb +5 -52
- data/lib/stormpath-sdk/resource/utils.rb +43 -13
- data/lib/stormpath-sdk/util/assert.rb +5 -15
- data/lib/stormpath-sdk/version.rb +3 -3
- data/spec/api_key_spec.rb +19 -0
- data/spec/auth/basic_authenticator_spec.rb +25 -0
- data/spec/auth/sauthc1_signer_spec.rb +42 -0
- data/spec/cache/cache_entry_spec.rb +157 -0
- data/spec/cache/cache_spec.rb +89 -0
- data/spec/cache/cache_stats_spec.rb +106 -0
- data/spec/client_spec.rb +538 -0
- data/spec/data_store_spec.rb +130 -0
- data/spec/resource/account_spec.rb +74 -0
- data/spec/resource/application_spec.rb +148 -0
- data/spec/resource/base_spec.rb +114 -0
- data/spec/resource/collection_spec.rb +169 -0
- data/spec/resource/directory_spec.rb +30 -0
- data/spec/resource/expansion_spec.rb +100 -0
- data/spec/resource/group_spec.rb +49 -0
- data/spec/spec_helper.rb +135 -0
- data/spec/support/resource_factory.rb +48 -0
- data/spec/support/resource_matchers.rb +27 -0
- data/spec/support/test_cache_stores.rb +9 -0
- data/spec/support/test_request_executor.rb +11 -0
- data/stormpath-sdk.gemspec +14 -4
- data/support/api.rb +55 -0
- metadata +214 -44
- data/lib/stormpath-sdk/client/client.rb +0 -38
- data/lib/stormpath-sdk/client/client_application.rb +0 -38
- data/lib/stormpath-sdk/client/client_application_builder.rb +0 -351
- data/lib/stormpath-sdk/client/client_builder.rb +0 -305
- data/lib/stormpath-sdk/ds/data_store.rb +0 -210
- data/lib/stormpath-sdk/ds/resource_factory.rb +0 -37
- data/lib/stormpath-sdk/resource/account_list.rb +0 -32
- data/lib/stormpath-sdk/resource/collection_resource.rb +0 -91
- data/lib/stormpath-sdk/resource/directory_list.rb +0 -30
- data/lib/stormpath-sdk/resource/group_membership_list.rb +0 -32
- data/lib/stormpath-sdk/resource/instance_resource.rb +0 -28
- data/lib/stormpath-sdk/resource/resource.rb +0 -327
- data/lib/stormpath-sdk/resource/resource_error.rb +0 -47
- data/test/client/client.yml +0 -16
- data/test/client/client_application_builder_spec.rb +0 -114
- data/test/client/client_builder_spec.rb +0 -176
- data/test/client/read_spec.rb +0 -254
- data/test/client/write_spec.rb +0 -420
- data/test/resource/resource_spec.rb +0 -41
- data/test/resource/test_resource.rb +0 -28
data/Rakefile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rubygems/package_task'
|
3
3
|
require 'rspec/core/rake_task'
|
4
|
+
require 'stormpath-sdk'
|
5
|
+
require './support/api'
|
4
6
|
|
5
7
|
spec = eval(File.read('stormpath-sdk.gemspec'))
|
6
8
|
|
@@ -13,4 +15,16 @@ RSpec::Core::RakeTask.new do |t|
|
|
13
15
|
t.rspec_opts = ['-c']
|
14
16
|
end
|
15
17
|
|
16
|
-
task :default => :spec
|
18
|
+
task :default => :spec
|
19
|
+
|
20
|
+
namespace :api do
|
21
|
+
task :clean do
|
22
|
+
Stormpath::Support::Api.destroy_resources(
|
23
|
+
ENV['STORMPATH_SDK_TEST_API_KEY_ID'],
|
24
|
+
ENV['STORMPATH_SDK_TEST_API_KEY_SECRET'],
|
25
|
+
ENV['STORMPATH_SDK_TEST_APPLICATION_URL'],
|
26
|
+
ENV['STORMPATH_SDK_TEST_DIRECTORY_URL'],
|
27
|
+
ENV['STORMPATH_SDK_TEST_DIRECTORY_WITH_VERIFICATION_URL']
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
data/lib/stormpath-sdk.rb
CHANGED
@@ -6,41 +6,62 @@ require "open-uri"
|
|
6
6
|
require "uri"
|
7
7
|
require "uuidtools"
|
8
8
|
require "yaml"
|
9
|
-
require "active_support"
|
9
|
+
require "active_support/core_ext"
|
10
|
+
require 'active_support/core_ext/module/delegation'
|
11
|
+
require 'active_support/core_ext/kernel/singleton_class'
|
12
|
+
require 'active_support/core_ext/array/wrap'
|
10
13
|
|
11
14
|
require "stormpath-sdk/version" unless defined? Stormpath::VERSION
|
15
|
+
|
12
16
|
require "stormpath-sdk/util/assert"
|
13
|
-
require "stormpath-sdk/
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
require "stormpath-sdk/ext/hash"
|
18
|
+
|
19
|
+
module Stormpath
|
20
|
+
autoload :Error, 'stormpath-sdk/error'
|
21
|
+
autoload :ApiKey, 'stormpath-sdk/api_key'
|
22
|
+
autoload :Client, 'stormpath-sdk/client'
|
23
|
+
autoload :DataStore, 'stormpath-sdk/data_store'
|
24
|
+
|
25
|
+
module Resource
|
26
|
+
autoload :Expansion, 'stormpath-sdk/resource/expansion'
|
27
|
+
autoload :Status, 'stormpath-sdk/resource/status'
|
28
|
+
autoload :Utils, 'stormpath-sdk/resource/utils'
|
29
|
+
autoload :Associations, 'stormpath-sdk/resource/associations'
|
30
|
+
autoload :Base, 'stormpath-sdk/resource/base'
|
31
|
+
autoload :Error, 'stormpath-sdk/resource/error'
|
32
|
+
autoload :Instance, 'stormpath-sdk/resource/instance'
|
33
|
+
autoload :Collection, 'stormpath-sdk/resource/collection'
|
34
|
+
autoload :Tenant, 'stormpath-sdk/resource/tenant'
|
35
|
+
autoload :Application, 'stormpath-sdk/resource/application'
|
36
|
+
autoload :Applications, 'stormpath-sdk/resource/applications'
|
37
|
+
autoload :Directory, 'stormpath-sdk/resource/directory'
|
38
|
+
autoload :Directories, 'stormpath-sdk/resource/directories'
|
39
|
+
autoload :Account, 'stormpath-sdk/resource/account'
|
40
|
+
autoload :Accounts, 'stormpath-sdk/resource/accounts'
|
41
|
+
autoload :Group, 'stormpath-sdk/resource/group'
|
42
|
+
autoload :Groups, 'stormpath-sdk/resource/groups'
|
43
|
+
autoload :EmailVerificationToken, 'stormpath-sdk/resource/email_verification_token'
|
44
|
+
autoload :GroupMembership, 'stormpath-sdk/resource/group_membership'
|
45
|
+
autoload :GroupMemberships, 'stormpath-sdk/resource/group_memberships'
|
46
|
+
autoload :PasswordResetToken, 'stormpath-sdk/resource/password_reset_token'
|
47
|
+
autoload :PasswordResetTokens, 'stormpath-sdk/resource/password_reset_tokens'
|
48
|
+
end
|
49
|
+
|
50
|
+
module Cache
|
51
|
+
autoload :CacheManager, 'stormpath-sdk/cache/cache_manager'
|
52
|
+
autoload :Cache, 'stormpath-sdk/cache/cache'
|
53
|
+
autoload :CacheEntry, 'stormpath-sdk/cache/cache_entry'
|
54
|
+
autoload :CacheStats, 'stormpath-sdk/cache/cache_stats'
|
55
|
+
autoload :MemoryStore, 'stormpath-sdk/cache/memory_store'
|
56
|
+
autoload :RedisStore, 'stormpath-sdk/cache/redis_store'
|
57
|
+
end
|
58
|
+
|
59
|
+
module Authentication
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
19
63
|
require "stormpath-sdk/auth/username_password_request"
|
20
|
-
require
|
21
|
-
require "stormpath-sdk/resource/utils"
|
22
|
-
require "stormpath-sdk/util/request_utils"
|
23
|
-
require "stormpath-sdk/resource/resource"
|
24
|
-
require "stormpath-sdk/resource/collection_resource"
|
25
|
-
require "stormpath-sdk/resource/instance_resource"
|
26
|
-
require "stormpath-sdk/resource/resource"
|
27
|
-
require "stormpath-sdk/resource/error"
|
28
|
-
require "stormpath-sdk/resource/resource_error"
|
29
|
-
require "stormpath-sdk/resource/error"
|
30
|
-
require "stormpath-sdk/resource/tenant"
|
31
|
-
require "stormpath-sdk/resource/directory"
|
32
|
-
require "stormpath-sdk/resource/tenant"
|
33
|
-
require "stormpath-sdk/resource/email_verification_token"
|
34
|
-
require "stormpath-sdk/resource/group_list"
|
35
|
-
require "stormpath-sdk/resource/account"
|
36
|
-
require "stormpath-sdk/resource/account_list"
|
37
|
-
require "stormpath-sdk/resource/password_reset_token"
|
38
|
-
require "stormpath-sdk/resource/application"
|
39
|
-
require "stormpath-sdk/resource/group"
|
40
|
-
require "stormpath-sdk/resource/application_list"
|
41
|
-
require "stormpath-sdk/resource/directory_list"
|
42
|
-
require "stormpath-sdk/resource/group_membership"
|
43
|
-
require "stormpath-sdk/resource/group_membership_list"
|
64
|
+
require 'stormpath-sdk/http/utils'
|
44
65
|
require "stormpath-sdk/http/request"
|
45
66
|
require "stormpath-sdk/http/response"
|
46
67
|
require "stormpath-sdk/http/authc/sauthc1_signer"
|
@@ -48,5 +69,3 @@ require "stormpath-sdk/http/http_client_request_executor"
|
|
48
69
|
require "stormpath-sdk/auth/basic_login_attempt"
|
49
70
|
require "stormpath-sdk/auth/authentication_result"
|
50
71
|
require "stormpath-sdk/auth/basic_authenticator"
|
51
|
-
require "stormpath-sdk/ds/resource_factory"
|
52
|
-
require "stormpath-sdk/ds/data_store"
|
@@ -15,18 +15,14 @@
|
|
15
15
|
#
|
16
16
|
module Stormpath
|
17
17
|
|
18
|
-
|
18
|
+
class ApiKey
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
def get_item_type
|
23
|
-
|
24
|
-
Group
|
25
|
-
|
26
|
-
end
|
20
|
+
attr_accessor :id, :secret
|
27
21
|
|
22
|
+
def initialize(id, secret)
|
23
|
+
@id = id
|
24
|
+
@secret = secret
|
28
25
|
end
|
29
|
-
|
30
26
|
end
|
31
27
|
|
32
28
|
end
|
@@ -14,19 +14,9 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
module Stormpath
|
17
|
-
|
18
17
|
module Authentication
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
ACCOUNT = "account"
|
23
|
-
|
24
|
-
def get_account
|
25
|
-
get_resource_property ACCOUNT, Stormpath::Resource::Account
|
26
|
-
end
|
27
|
-
|
18
|
+
class AuthenticationResult < Stormpath::Resource::Base
|
19
|
+
has_one :account
|
28
20
|
end
|
29
|
-
|
30
21
|
end
|
31
|
-
|
32
|
-
end
|
22
|
+
end
|
@@ -14,11 +14,8 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
module Stormpath
|
17
|
-
|
18
17
|
module Authentication
|
19
|
-
|
20
18
|
class BasicAuthenticator
|
21
|
-
|
22
19
|
include Stormpath::Util::Assert
|
23
20
|
|
24
21
|
def initialize data_store
|
@@ -26,14 +23,13 @@ module Stormpath
|
|
26
23
|
end
|
27
24
|
|
28
25
|
def authenticate parent_href, request
|
29
|
-
|
30
26
|
assert_not_nil parent_href, "parentHref argument must be specified"
|
31
27
|
assert_kind_of UsernamePasswordRequest, request, "Only UsernamePasswordRequest instances are supported."
|
32
28
|
|
33
|
-
username = request.
|
29
|
+
username = request.principals
|
34
30
|
username = (username != nil) ? username : ''
|
35
31
|
|
36
|
-
password = request.
|
32
|
+
password = request.credentials
|
37
33
|
pw_string = password.join
|
38
34
|
|
39
35
|
value = username + ':' + pw_string
|
@@ -41,8 +37,8 @@ module Stormpath
|
|
41
37
|
value = Base64.encode64(value).tr("\n", '')
|
42
38
|
|
43
39
|
attempt = @data_store.instantiate BasicLoginAttempt, nil
|
44
|
-
attempt.
|
45
|
-
attempt.
|
40
|
+
attempt.type = 'basic'
|
41
|
+
attempt.value = value
|
46
42
|
|
47
43
|
href = parent_href + '/loginAttempts'
|
48
44
|
|
@@ -51,7 +47,5 @@ module Stormpath
|
|
51
47
|
end
|
52
48
|
|
53
49
|
end
|
54
|
-
|
55
50
|
end
|
56
|
-
|
57
|
-
end
|
51
|
+
end
|
@@ -14,27 +14,25 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
module Stormpath
|
17
|
-
|
18
17
|
module Authentication
|
19
|
-
|
20
|
-
class BasicLoginAttempt < Stormpath::Resource::Resource
|
18
|
+
class BasicLoginAttempt < Stormpath::Resource::Base
|
21
19
|
|
22
20
|
TYPE = "type"
|
23
21
|
VALUE = "value"
|
24
22
|
|
25
|
-
def
|
23
|
+
def type
|
26
24
|
get_property TYPE
|
27
25
|
end
|
28
26
|
|
29
|
-
def
|
27
|
+
def type=(type)
|
30
28
|
set_property TYPE, type
|
31
29
|
end
|
32
30
|
|
33
|
-
def
|
31
|
+
def value
|
34
32
|
get_property VALUE
|
35
33
|
end
|
36
34
|
|
37
|
-
def
|
35
|
+
def value=(value)
|
38
36
|
set_property VALUE, value
|
39
37
|
end
|
40
38
|
|
@@ -42,4 +40,4 @@ module Stormpath
|
|
42
40
|
|
43
41
|
end
|
44
42
|
|
45
|
-
end
|
43
|
+
end
|
@@ -27,17 +27,14 @@ module Stormpath
|
|
27
27
|
@host = host
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
30
|
+
def principals
|
31
31
|
@username
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
34
|
+
def credentials
|
35
35
|
@password
|
36
36
|
end
|
37
37
|
|
38
|
-
##
|
39
|
-
# Clears out (nulls) the username, password, and host. The password bytes are explicitly set to
|
40
|
-
# <tt>0x00</tt> to eliminate the possibility of memory access at a later time.
|
41
38
|
def clear
|
42
39
|
@username = nil
|
43
40
|
@host = nil
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Stormpath
|
2
|
+
module Cache
|
3
|
+
DEFAULT_STORE = MemoryStore
|
4
|
+
DEFAULT_TTL_SECONDS = 5 * 60
|
5
|
+
DEFAULT_TTI_SECONDS = 5 * 60
|
6
|
+
|
7
|
+
class Cache
|
8
|
+
attr_reader :stats, :ttl_seconds, :tti_seconds
|
9
|
+
|
10
|
+
def initialize(opts = {})
|
11
|
+
@ttl_seconds = opts[:ttl_seconds] || DEFAULT_TTL_SECONDS
|
12
|
+
@tti_seconds = opts[:tti_seconds] || DEFAULT_TTI_SECONDS
|
13
|
+
store_opts = opts[:store_opts] || {}
|
14
|
+
@store = (opts[:store] || DEFAULT_STORE).new store_opts
|
15
|
+
@stats = CacheStats.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def get(k)
|
19
|
+
if entry = @store.get(k)
|
20
|
+
if entry.expired? @ttl_seconds, @tti_seconds
|
21
|
+
@stats.miss true
|
22
|
+
@store.delete k
|
23
|
+
nil
|
24
|
+
else
|
25
|
+
@stats.hit
|
26
|
+
entry.touch
|
27
|
+
entry.value
|
28
|
+
end
|
29
|
+
else
|
30
|
+
@stats.miss
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def put(k, v)
|
36
|
+
@store.put k, CacheEntry.new(v)
|
37
|
+
@stats.put
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete(k)
|
41
|
+
@store.delete k
|
42
|
+
@stats.delete
|
43
|
+
end
|
44
|
+
|
45
|
+
def clear
|
46
|
+
@store.clear
|
47
|
+
end
|
48
|
+
|
49
|
+
def size
|
50
|
+
@stats.size
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Stormpath
|
2
|
+
module Cache
|
3
|
+
class CacheEntry
|
4
|
+
attr_accessor :value, :created_at, :last_accessed_at
|
5
|
+
|
6
|
+
def initialize value
|
7
|
+
self.value = value
|
8
|
+
self.created_at = Time.now
|
9
|
+
self.last_accessed_at = created_at
|
10
|
+
end
|
11
|
+
|
12
|
+
def touch
|
13
|
+
self.last_accessed_at = Time.now
|
14
|
+
end
|
15
|
+
|
16
|
+
def expired? ttl_seconds, tti_seconds
|
17
|
+
now = Time.now
|
18
|
+
now > (created_at + ttl_seconds) || now > (last_accessed_at + tti_seconds)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_h
|
22
|
+
{ 'value' => value, 'created_at' => created_at, 'last_accessed_at' => last_accessed_at }
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_h(hash)
|
26
|
+
CacheEntry.new(hash['value']).tap do |cache_entry|
|
27
|
+
cache_entry.created_at = Time.parse(hash['created_at'])
|
28
|
+
cache_entry.last_accessed_at = Time.parse(hash['last_accessed_at'])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Stormpath
|
2
|
+
module Cache
|
3
|
+
class CacheManager
|
4
|
+
|
5
|
+
def initialize(opts = nil)
|
6
|
+
@caches = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_cache(region, opts)
|
10
|
+
@caches[region] = Cache.new opts
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_cache(region)
|
14
|
+
@caches[region]
|
15
|
+
end
|
16
|
+
|
17
|
+
def stats
|
18
|
+
Hash[ @caches.map { |region, cache| [region, cache.stats] } ]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Stormpath
|
2
|
+
module Cache
|
3
|
+
class CacheStats
|
4
|
+
attr_accessor :puts, :hits, :misses, :expirations, :size
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@puts = @hits = @misses = @expirations = @size = 0
|
8
|
+
end
|
9
|
+
|
10
|
+
def put
|
11
|
+
@puts += 1
|
12
|
+
@size += 1
|
13
|
+
end
|
14
|
+
|
15
|
+
def hit
|
16
|
+
@hits += 1
|
17
|
+
end
|
18
|
+
|
19
|
+
def miss(expired = false)
|
20
|
+
@misses += 1
|
21
|
+
@expirations += 1 if expired
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete
|
25
|
+
if @size > 0
|
26
|
+
@size -= 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def summary
|
31
|
+
[@puts, @hits, @misses, @expirations, @size]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Stormpath
|
2
|
+
module Cache
|
3
|
+
class MemoryStore
|
4
|
+
def initialize(opts = nil)
|
5
|
+
@store = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def get(key)
|
9
|
+
@store[key]
|
10
|
+
end
|
11
|
+
|
12
|
+
def put(key, entry)
|
13
|
+
@store[key] = entry
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(key)
|
17
|
+
@store.delete key
|
18
|
+
end
|
19
|
+
|
20
|
+
def clear
|
21
|
+
@store.clear
|
22
|
+
end
|
23
|
+
|
24
|
+
def size
|
25
|
+
@store.size
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|