stormpath-sdk 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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