stormpath-sdk 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.
Files changed (47) hide show
  1. data/Gemfile +4 -0
  2. data/README.md +24 -0
  3. data/Rakefile +16 -0
  4. data/lib/stormpath-sdk.rb +49 -0
  5. data/lib/stormpath-sdk/auth/authentication_result.rb +17 -0
  6. data/lib/stormpath-sdk/auth/basic_authenticator.rb +42 -0
  7. data/lib/stormpath-sdk/auth/basic_login_attempt.rb +30 -0
  8. data/lib/stormpath-sdk/auth/username_password_request.rb +43 -0
  9. data/lib/stormpath-sdk/client/api_key.rb +18 -0
  10. data/lib/stormpath-sdk/client/client.rb +23 -0
  11. data/lib/stormpath-sdk/client/client_builder.rb +291 -0
  12. data/lib/stormpath-sdk/ds/data_store.rb +150 -0
  13. data/lib/stormpath-sdk/ds/resource_factory.rb +22 -0
  14. data/lib/stormpath-sdk/http/authc/sauthc1_signer.rb +216 -0
  15. data/lib/stormpath-sdk/http/http_client_request_executor.rb +69 -0
  16. data/lib/stormpath-sdk/http/request.rb +83 -0
  17. data/lib/stormpath-sdk/http/response.rb +35 -0
  18. data/lib/stormpath-sdk/resource/account.rb +110 -0
  19. data/lib/stormpath-sdk/resource/account_list.rb +17 -0
  20. data/lib/stormpath-sdk/resource/application.rb +95 -0
  21. data/lib/stormpath-sdk/resource/application_list.rb +17 -0
  22. data/lib/stormpath-sdk/resource/collection_resource.rb +76 -0
  23. data/lib/stormpath-sdk/resource/directory.rb +76 -0
  24. data/lib/stormpath-sdk/resource/directory_list.rb +15 -0
  25. data/lib/stormpath-sdk/resource/email_verification_token.rb +11 -0
  26. data/lib/stormpath-sdk/resource/error.rb +42 -0
  27. data/lib/stormpath-sdk/resource/group.rb +73 -0
  28. data/lib/stormpath-sdk/resource/group_list.rb +18 -0
  29. data/lib/stormpath-sdk/resource/group_membership.rb +55 -0
  30. data/lib/stormpath-sdk/resource/group_membership_list.rb +17 -0
  31. data/lib/stormpath-sdk/resource/instance_resource.rb +13 -0
  32. data/lib/stormpath-sdk/resource/password_reset_token.rb +27 -0
  33. data/lib/stormpath-sdk/resource/resource.rb +173 -0
  34. data/lib/stormpath-sdk/resource/resource_error.rb +32 -0
  35. data/lib/stormpath-sdk/resource/status.rb +19 -0
  36. data/lib/stormpath-sdk/resource/tenant.rb +55 -0
  37. data/lib/stormpath-sdk/resource/utils.rb +16 -0
  38. data/lib/stormpath-sdk/util/assert.rb +26 -0
  39. data/lib/stormpath-sdk/util/hash.rb +17 -0
  40. data/lib/stormpath-sdk/util/request_utils.rb +57 -0
  41. data/lib/stormpath-sdk/version.rb +4 -0
  42. data/stormpath-sdk.gemspec +29 -0
  43. data/test/client/client.yml +16 -0
  44. data/test/client/clientbuilder_spec.rb +176 -0
  45. data/test/client/read_spec.rb +243 -0
  46. data/test/client/write_spec.rb +315 -0
  47. metadata +226 -0
@@ -0,0 +1,32 @@
1
+ module Stormpath
2
+
3
+ module Resource
4
+
5
+ class ResourceError < RuntimeError
6
+
7
+ def initialize error
8
+ super !error.nil? ? error.get_message : ''
9
+ @error = error
10
+ end
11
+
12
+ def get_status
13
+ !@error.nil? ? @error.get_status : -1
14
+ end
15
+
16
+ def get_code
17
+ !@error.nil? ? @error.get_code : -1
18
+ end
19
+
20
+ def get_developer_message
21
+ !@error.nil? ? @error.get_developer_message : nil
22
+ end
23
+
24
+ def get_more_info
25
+ !@error.nil? ? @error.get_more_info : nil
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
32
+
@@ -0,0 +1,19 @@
1
+ module Stormpath
2
+
3
+ module Resource
4
+
5
+ module Status
6
+
7
+ ENABLED = 'ENABLED'
8
+ DISABLED = 'DISABLED'
9
+
10
+ def get_status_hash
11
+ {ENABLED => ENABLED, DISABLED => DISABLED}
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+
@@ -0,0 +1,55 @@
1
+ module Stormpath
2
+
3
+ module Resource
4
+
5
+ class Tenant < InstanceResource
6
+
7
+ NAME = "name"
8
+ KEY = "key"
9
+ APPLICATIONS = "applications"
10
+ DIRECTORIES = "directories"
11
+
12
+ def get_name
13
+ get_property NAME
14
+ end
15
+
16
+ def get_key
17
+ get_property KEY
18
+ end
19
+
20
+ def create_application application
21
+
22
+ href = "/applications"; #TODO: enable auto discovery
23
+ data_store.create href, application, Application
24
+
25
+ end
26
+
27
+ def get_applications
28
+
29
+ get_resource_property APPLICATIONS, ApplicationList
30
+
31
+ end
32
+
33
+ def get_directories
34
+
35
+ get_resource_property DIRECTORIES, DirectoryList
36
+
37
+ end
38
+
39
+ def verify_account_email token
40
+
41
+ #TODO: enable auto discovery via Tenant resource (should be just /emailVerificationTokens)
42
+ href = "/accounts/emailVerificationTokens/" + token
43
+
44
+ token_hash = Hash.new
45
+ token_hash.store HREF_PROP_NAME, href
46
+
47
+ ev_token = data_store.instantiate EmailVerificationToken, token_hash
48
+
49
+ #execute a POST (should clean this up / make it more obvious)
50
+ data_store.save ev_token, Account
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,16 @@
1
+ module Stormpath
2
+
3
+ module Resource
4
+
5
+ module Utils
6
+
7
+ def to_class_from_instance resource
8
+
9
+ if resource.kind_of? Resource
10
+ clazz = Kernel.const_get resource.class.name.split('::').last
11
+ end
12
+ clazz
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ module Stormpath
2
+
3
+ module Util
4
+
5
+ module Assert
6
+
7
+ def assert_not_nil object, message
8
+
9
+ raise ArgumentError, message, caller unless !object.nil?
10
+
11
+ end
12
+
13
+ def assert_kind_of clazz, object, message
14
+
15
+ raise ArgumentError, message, caller unless object.kind_of? clazz
16
+
17
+ end
18
+
19
+ def assert_true arg, message
20
+
21
+ raise ArgumentError, message, caller unless arg
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ class Hash
2
+
3
+ # implementation borrowed from the vine project at
4
+ # https://github.com/guangnan/vine/blob/master/lib/vine.rb
5
+ def access(path, separator)
6
+ ret = self
7
+ path.split(separator).each do |p|
8
+ if p.to_i.to_s == p
9
+ ret = ret[p.to_i]
10
+ else
11
+ ret = ret[p.to_s] || ret[p.to_sym]
12
+ end
13
+ break unless ret
14
+ end
15
+ ret
16
+ end
17
+ end
@@ -0,0 +1,57 @@
1
+ module Stormpath
2
+
3
+ module Util
4
+
5
+ class RequestUtils
6
+
7
+ ##
8
+ # Returns true if the specified URI uses a standard port (i.e. http == 80 or https == 443),
9
+ # false otherwise.
10
+ #
11
+ # param uri
12
+ # return true if the specified URI is using a non-standard port, false otherwise
13
+ #
14
+ def self.default_port? uri
15
+ scheme = uri.scheme.downcase
16
+ port = uri.port
17
+ port <= 0 || (port == 80 && scheme.eql?("http")) || (port == 443 && scheme.eql?("https"))
18
+ end
19
+
20
+ def self.encode_url value, path, canonical
21
+
22
+ encoded = URI.escape value
23
+
24
+ if canonical
25
+
26
+ str_map = {'+' => '%20', '*' => '%2A', '%7E' => '~'}
27
+
28
+ str_map.each do |key, str_value|
29
+
30
+ if encoded.include? key
31
+ encoded[key] = str_value
32
+ end
33
+
34
+ end
35
+
36
+ # encoded['%7E'] = '~' --> yes, this is reversed (compared to the other two) intentionally
37
+
38
+ if path
39
+
40
+ str = '%2F'
41
+ if encoded.include? str
42
+ encoded[str] = '/'
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ encoded
50
+
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,4 @@
1
+ module Stormpath
2
+ VERSION = '0.1.0'
3
+ VERSION_DATE = '2012-07-27'
4
+ end
@@ -0,0 +1,29 @@
1
+ require "./lib/stormpath-sdk/version"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'stormpath-sdk'
5
+ s.version = Stormpath::VERSION
6
+ s.date = Stormpath::VERSION_DATE
7
+ s.summary = "Stormpath SDK"
8
+ s.description = "Stormpath SDK used to interact with the Stormpath REST API"
9
+ s.authors = ["Elder Crisostomo"]
10
+ s.email = 'elder@stormpath.com'
11
+ s.homepage = 'https://github.com/stormpath/stormpath-sdk-ruby'
12
+
13
+ s.platform = Gem::Platform::RUBY
14
+ s.require_paths = %w[lib]
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = Dir['test/**/*.rb']
17
+
18
+ s.add_dependency('multi_json', '>= 1.3.6')
19
+ s.add_dependency('httpclient', '>= 2.2.5')
20
+ s.add_dependency('uuidtools', '>= 2.1.3')
21
+
22
+ s.add_development_dependency 'rake', '~> 0.9.2'
23
+ s.add_development_dependency 'rspec-core', '~> 2.10.1'
24
+ s.add_development_dependency 'rspec-expectations', '~> 2.10.0'
25
+ s.add_development_dependency 'rspec-mocks', '~> 2.10.1'
26
+ s.add_development_dependency 'rack', '~> 1.4.1'
27
+
28
+ s.rdoc_options = ['--line-numbers', '--inline-source', '--title', 'stormpath-sdk', '--main']
29
+ end
@@ -0,0 +1,16 @@
1
+ apiKey.id: myApiKeyId
2
+ apiKey.secret: myApkiKeySecret
3
+
4
+ different.apiKey.id: myApiKeyId
5
+ different.apiKey.secret: myApkiKeySecret
6
+
7
+
8
+ stormpath:
9
+ apiKey:
10
+ id: myApiKeyId
11
+ secret: myApkiKeySecret
12
+
13
+ different.stormpath:
14
+ different.apiKey:
15
+ different.id: myApiKeyId
16
+ different.secret: myApkiKeySecret
@@ -0,0 +1,176 @@
1
+ require "stormpath-sdk"
2
+
3
+ include Stormpath::Client
4
+
5
+ describe "Client Builder Tests" do
6
+
7
+ before(:all) do
8
+ @client_file = 'test/client/client.yml'
9
+ @client_remote_file = 'http://localhost:8081/client.yml'
10
+ @test_remote_file = false
11
+ end
12
+
13
+
14
+ it 'Builder should read default properties from YAML file location' do
15
+
16
+ result = ClientBuilder.new.
17
+ set_api_key_file_location(@client_file).
18
+ build
19
+
20
+ result.should be_kind_of Client
21
+
22
+ end
23
+
24
+ it 'Builder should read default properties from YAML FILE object' do
25
+
26
+ result = ClientBuilder.new.
27
+ set_api_key_file(File.open(@client_file)).
28
+ build
29
+
30
+ result.should be_kind_of Client
31
+
32
+ end
33
+
34
+ it 'Builder should read custom simple properties from YAML file location' do
35
+
36
+ result = ClientBuilder.new.
37
+ set_api_key_file_location(@client_file).
38
+ set_api_key_id_property_name('different.apiKey.id').
39
+ set_api_key_secret_property_name('different.apiKey.secret').
40
+ build
41
+
42
+ result.should be_kind_of Client
43
+
44
+ end
45
+
46
+ it 'Builder should read default properties from YAML valid object' do
47
+
48
+ # getting the properties from file...just to avoid writing them directly
49
+ # in the 'properties' Hash
50
+ yml_obj = YAML::load(File.open @client_file)
51
+ api_key_id_keyword = 'apiKey.id'
52
+ api_key_secret_keyword = 'apiKey.secret'
53
+
54
+ # we create the client from this Hash instead of from a file
55
+ properties = {api_key_id_keyword => yml_obj[api_key_id_keyword],
56
+ api_key_secret_keyword => yml_obj[api_key_secret_keyword]}
57
+
58
+ result = ClientBuilder.new.
59
+ set_api_key_properties(properties.to_yaml).
60
+ build
61
+
62
+ result.should be_kind_of Client
63
+
64
+ end
65
+
66
+ it 'Builder should read custom simple properties from YAML valid object' do
67
+
68
+ # getting the properties from file...just to avoid writing them directly
69
+ # in the 'properties' Hash
70
+ yml_obj = YAML::load(File.open @client_file)
71
+ api_key_id_keyword = 'different.apiKey.id'
72
+ api_key_secret_keyword = 'different.apiKey.secret'
73
+
74
+ # we create the client from this Hash instead of from a file
75
+ properties = {api_key_id_keyword => yml_obj[api_key_id_keyword],
76
+ api_key_secret_keyword => yml_obj[api_key_secret_keyword]}
77
+
78
+ result = ClientBuilder.new.
79
+ set_api_key_properties(properties.to_yaml).
80
+ set_api_key_id_property_name(api_key_id_keyword).
81
+ set_api_key_secret_property_name(api_key_secret_keyword).
82
+ build
83
+
84
+ result.should be_kind_of Client
85
+
86
+ end
87
+
88
+ it 'Builder should read custom complex properties from YAML file location' do
89
+
90
+ result = ClientBuilder.new.
91
+ set_api_key_file_location(@client_file).
92
+ set_api_key_id_property_name('stormpath', 'apiKey', 'id').
93
+ set_api_key_secret_property_name('stormpath', 'apiKey', 'secret').
94
+ build
95
+
96
+ result.should be_kind_of Client
97
+
98
+ end
99
+
100
+ it 'Builder should read custom complex properties from YAML valid object' do
101
+
102
+ # getting the properties from file...just to avoid writing them directly
103
+ # in the 'properties' Hash
104
+ yml_obj = YAML::load(File.open @client_file)
105
+ stormpath = 'different.stormpath'
106
+ api_key = 'different.apiKey'
107
+ id = 'different.id'
108
+ secret = 'different.secret'
109
+
110
+ # we create the client from this Hash instead of from a file
111
+ data = {id => yml_obj[stormpath][api_key][id],
112
+ secret => yml_obj[stormpath][api_key][secret]}
113
+ api_key_data = {api_key => data}
114
+ stormpath_data = {stormpath => api_key_data}
115
+
116
+ result = ClientBuilder.new.
117
+ set_api_key_properties(stormpath_data.to_yaml).
118
+ set_api_key_id_property_name(stormpath, api_key, id).
119
+ set_api_key_secret_property_name(stormpath, api_key, secret).
120
+ build
121
+
122
+ result.should be_kind_of Client
123
+
124
+ end
125
+
126
+ it 'Builder should read custom complex properties from YAML file location
127
+ and retrieve a Tenant from the Stormpath REST API' do
128
+
129
+ client = ClientBuilder.new.
130
+ set_api_key_file_location(@client_file).
131
+ set_api_key_id_property_name('stormpath', 'apiKey', 'id').
132
+ set_api_key_secret_property_name('stormpath', 'apiKey', 'secret').
133
+ #set_base_url('http://localhost:8080/v1').
134
+ build
135
+
136
+ result = client.current_tenant
137
+
138
+ result.should be_kind_of Tenant
139
+
140
+ end
141
+
142
+ it 'Builder should read default properties from YAML URL location
143
+ and retrieve a Tenant from the Stormpath REST API' do
144
+
145
+ if @test_remote_file
146
+
147
+ client = ClientBuilder.new.
148
+ set_api_key_file_location(@client_remote_file).
149
+ #set_base_url('http://localhost:8080/v1').
150
+ build
151
+
152
+ result = client.current_tenant
153
+
154
+ result.should be_kind_of Tenant
155
+ end
156
+
157
+
158
+ end
159
+
160
+ it 'Builder should read custom complex properties from YAML file URL location
161
+ and retrieve a Tenant from the Stormpath REST API' do
162
+
163
+ client = ClientBuilder.new.
164
+ set_api_key_file_location(@client_remote_file).
165
+ set_api_key_id_property_name('stormpath', 'apiKey', 'id').
166
+ set_api_key_secret_property_name('stormpath', 'apiKey', 'secret').
167
+ #set_base_url('http://localhost:8080/v1').
168
+ build
169
+
170
+ result = client.current_tenant
171
+
172
+ result.should be_kind_of Tenant
173
+
174
+ end
175
+
176
+ end