ixtlan-remote 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 (89) hide show
  1. data/Gemfile +2 -0
  2. data/README.md +64 -0
  3. data/agpl-3.0.txt +661 -0
  4. data/lib/ixtlan-remote.rb +23 -0
  5. data/lib/ixtlan/passwords.rb +52 -0
  6. data/lib/ixtlan/passwords.rb~ +47 -0
  7. data/lib/ixtlan/railtie.rb~ +17 -0
  8. data/lib/ixtlan/remote.rb +23 -0
  9. data/lib/ixtlan/remote/access_controller.rb +62 -0
  10. data/lib/ixtlan/remote/access_controller.rb~ +25 -0
  11. data/lib/ixtlan/remote/constant_time_compare.rb +39 -0
  12. data/lib/ixtlan/remote/constant_time_compare.rb~ +19 -0
  13. data/lib/ixtlan/remote/heartbeat.rb~ +80 -0
  14. data/lib/ixtlan/remote/model_conversion.rb~ +245 -0
  15. data/lib/ixtlan/remote/model_helpers.rb +73 -0
  16. data/lib/ixtlan/remote/model_helpers.rb~ +53 -0
  17. data/lib/ixtlan/remote/permission.rb +40 -0
  18. data/lib/ixtlan/remote/permission.rb~ +19 -0
  19. data/lib/ixtlan/remote/railtie.rb +30 -0
  20. data/lib/ixtlan/remote/railtie.rb~ +9 -0
  21. data/lib/ixtlan/remote/remote_access_controller.rb~ +25 -0
  22. data/lib/ixtlan/remote/remote_permisson.rb~ +9 -0
  23. data/lib/ixtlan/remote/resource.rb +145 -0
  24. data/lib/ixtlan/remote/resource.rb-~ +165 -0
  25. data/lib/ixtlan/remote/resource.rb~ +152 -0
  26. data/lib/ixtlan/remote/rest.rb +108 -0
  27. data/lib/ixtlan/remote/rest.rb~ +83 -0
  28. data/lib/ixtlan/remote/rest_resource.rb~ +140 -0
  29. data/lib/ixtlan/remote/rest_resource_config.rb~ +63 -0
  30. data/lib/ixtlan/remote/rest_resource_factory.rb~ +259 -0
  31. data/lib/ixtlan/remote/rest_resource_old.rb-~ +259 -0
  32. data/lib/ixtlan/remote/server.rb +119 -0
  33. data/lib/ixtlan/remote/server.rb~ +82 -0
  34. data/lib/ixtlan/remote/summary.rb +46 -0
  35. data/lib/ixtlan/remote/summary.rb~ +23 -0
  36. data/lib/ixtlan/remote/sync.rb +104 -0
  37. data/lib/ixtlan/remote/sync.rb~ +78 -0
  38. data/lib/ixtlan/remote/sync_summary.rb~ +23 -0
  39. data/lib/ixtlan/remote/tranlation_key.rb~ +7 -0
  40. data/lib/ixtlan/remote/translation.rake~ +194 -0
  41. data/lib/ixtlan/remote/translation_models.rb~ +11 -0
  42. data/lib/ixtlan/remote/updater.rb~ +71 -0
  43. data/lib/ixtlan/user_management/application_model.rb +30 -0
  44. data/lib/ixtlan/user_management/application_model.rb~ +21 -0
  45. data/lib/ixtlan/user_management/application_resource.rb +48 -0
  46. data/lib/ixtlan/user_management/application_resource.rb~ +21 -0
  47. data/lib/ixtlan/user_management/authentcator.rb~ +31 -0
  48. data/lib/ixtlan/user_management/authentication_model.rb +31 -0
  49. data/lib/ixtlan/user_management/authentication_model.rb~ +21 -0
  50. data/lib/ixtlan/user_management/authenticator.rb +55 -0
  51. data/lib/ixtlan/user_management/authenticator.rb~ +20 -0
  52. data/lib/ixtlan/user_management/domain_resource.rb +48 -0
  53. data/lib/ixtlan/user_management/domain_resource.rb~ +21 -0
  54. data/lib/ixtlan/user_management/dummy_authentication.rb +50 -0
  55. data/lib/ixtlan/user_management/dummy_authentication.rb~ +49 -0
  56. data/lib/ixtlan/user_management/group.rb~ +39 -0
  57. data/lib/ixtlan/user_management/group_model.rb +31 -0
  58. data/lib/ixtlan/user_management/group_model.rb~ +21 -0
  59. data/lib/ixtlan/user_management/models.rb~ +39 -0
  60. data/lib/ixtlan/user_management/session-serializer.rb~ +18 -0
  61. data/lib/ixtlan/user_management/session_cuba.rb +47 -0
  62. data/lib/ixtlan/user_management/session_cuba.rb~ +44 -0
  63. data/lib/ixtlan/user_management/session_manager.rb +38 -0
  64. data/lib/ixtlan/user_management/session_model.rb +36 -0
  65. data/lib/ixtlan/user_management/session_model.rb~ +10 -0
  66. data/lib/ixtlan/user_management/session_plugin.rb +32 -0
  67. data/lib/ixtlan/user_management/session_serializer.rb +21 -0
  68. data/lib/ixtlan/user_management/session_serializer.rb~ +21 -0
  69. data/lib/ixtlan/user_management/user.rb~ +16 -0
  70. data/lib/ixtlan/user_management/user_model.rb +36 -0
  71. data/lib/ixtlan/user_management/user_model.rb~ +33 -0
  72. data/lib/ixtlan/user_management/user_resource.rb +55 -0
  73. data/lib/ixtlan/user_management/user_resource.rb~ +24 -0
  74. data/lib/ixtlan/user_management/user_serializer.rb +15 -0
  75. data/lib/ixtlan/user_management/user_serializer.rb~ +23 -0
  76. data/spec/access_controller_spec.rb +65 -0
  77. data/spec/access_controller_spec.rb~ +65 -0
  78. data/spec/model_helpers_spec.rb +40 -0
  79. data/spec/model_helpers_spec.rb~ +36 -0
  80. data/spec/remote_access_controller_spec.rb~ +36 -0
  81. data/spec/resource_spec.rb +181 -0
  82. data/spec/resource_spec.rb~ +173 -0
  83. data/spec/rest_resource_spec.rb~ +173 -0
  84. data/spec/rest_spec.rb +94 -0
  85. data/spec/rest_spec.rb~ +99 -0
  86. data/spec/rest_with_attribute_name_like_model_name_spec.rb +82 -0
  87. data/spec/sync_spec.rb +83 -0
  88. data/spec/sync_spec.rb~ +81 -0
  89. metadata +313 -0
@@ -0,0 +1,23 @@
1
+ require 'ixtlan/babel/serializer'
2
+ class UserSerializer < Ixtlan::Babel::Serializer
3
+
4
+ add_context(:session,
5
+ :only => [:id],
6
+ :include=> {
7
+ :groups => {
8
+ :only => [:name],
9
+ :include => {
10
+ :locales => {
11
+ :only => [:id, :code]
12
+ },
13
+ :domains => {
14
+ :only => [:id, :name]
15
+ },
16
+ :application => {
17
+ :only => [:id, :name]
18
+ }
19
+ }
20
+ }
21
+ })
22
+
23
+ end
@@ -0,0 +1,65 @@
1
+ require 'dm-sqlite-adapter'
2
+ require 'dm-migrations'
3
+ require 'ixtlan/remote/permission'
4
+ require 'ixtlan/remote/access_controller'
5
+
6
+ DataMapper.setup(:default, 'sqlite::memory:')
7
+ Ixtlan::Remote::Permission.auto_migrate!
8
+ Ixtlan::Remote::Permission.create(:allowed_ip => '1.1.1.1', :authentication_token => 'behappy')
9
+ Ixtlan::Remote::Permission.create(:authentication_token => 'be happy')
10
+
11
+ class Controller
12
+ include Ixtlan::Remote::AccessController
13
+
14
+ def new_request
15
+ r = Object.new
16
+ def r.headers
17
+ @m ||= {}
18
+ end
19
+ def r.remote_ip(p = nil)
20
+ @i = p if p
21
+ @i
22
+ end
23
+ r
24
+ end
25
+ def request
26
+ @r ||= new_request
27
+ end
28
+ end
29
+
30
+ describe Ixtlan::Remote::AccessController do
31
+
32
+ subject { Controller.new }
33
+
34
+ it 'should raise when there is no token' do
35
+ subject.request.headers.clear
36
+
37
+ lambda {subject.remote_permission}.must_raise RuntimeError
38
+ end
39
+
40
+ it 'should raise wrong authentication' do
41
+ subject.request.headers['X-SERVICE-TOKEN'] = 'something'
42
+
43
+ lambda {subject.remote_permission}.must_raise RuntimeError
44
+ end
45
+
46
+ it 'should pass without permission IP' do
47
+ subject.request.headers['X-SERVICE-TOKEN'] = 'be happy'
48
+
49
+ subject.remote_permission.authentication_token.must_equal 'be happy'
50
+ end
51
+
52
+ it 'should fail with wrong IP' do
53
+ subject.request.headers['X-SERVICE-TOKEN'] = 'behappy'
54
+
55
+ lambda {subject.remote_permission}.must_raise RuntimeError
56
+ end
57
+
58
+ it 'should pass with right IP' do
59
+ subject.request.headers['X-SERVICE-TOKEN'] = 'behappy'
60
+ subject.request.remote_ip '1.1.1.1'
61
+
62
+ subject.remote_permission.authentication_token.must_equal 'behappy'
63
+ subject.remote_permission.allowed_ip.must_equal '1.1.1.1'
64
+ end
65
+ end
@@ -0,0 +1,65 @@
1
+ require 'dm-sqlite-adapter'
2
+ require 'dm-migrations'
3
+ require 'ixtlan/remote/permission'
4
+ require 'ixtlan/remote/access_controller'
5
+
6
+ DataMapper.setup(:default, 'sqlite::memory:')
7
+ Ixtlan::Remote::Permission.auto_migrate!
8
+ Ixtlan::Remote::Permission.create(:ip => '1.1.1.1', :token => 'behappy')
9
+ Ixtlan::Remote::Permission.create(:token => 'be happy')
10
+
11
+ class Controller
12
+ include Ixtlan::Remote::AccessController
13
+
14
+ def new_request
15
+ r = Object.new
16
+ def r.headers
17
+ @m ||= {}
18
+ end
19
+ def r.remote_ip(p = nil)
20
+ @i = p if p
21
+ @i
22
+ end
23
+ r
24
+ end
25
+ def request
26
+ @r ||= new_request
27
+ end
28
+ end
29
+
30
+ describe Ixtlan::Remote::AccessController do
31
+
32
+ subject { Controller.new }
33
+
34
+ it 'should raise when there is no token' do
35
+ subject.request.headers.clear
36
+
37
+ lambda {subject.remote_permission}.must_raise RuntimeError
38
+ end
39
+
40
+ it 'should raise wrong authentication' do
41
+ subject.request.headers['X-SERVICE-TOKEN'] = 'something'
42
+
43
+ lambda {subject.remote_permission}.must_raise RuntimeError
44
+ end
45
+
46
+ it 'should pass without permission IP' do
47
+ subject.request.headers['X-SERVICE-TOKEN'] = 'be happy'
48
+
49
+ subject.remote_permission.token.must_equal 'be happy'
50
+ end
51
+
52
+ it 'should fail with wrong IP' do
53
+ subject.request.headers['X-SERVICE-TOKEN'] = 'behappy'
54
+
55
+ lambda {subject.remote_permission}.must_raise RuntimeError
56
+ end
57
+
58
+ it 'should pass with right IP' do
59
+ subject.request.headers['X-SERVICE-TOKEN'] = 'behappy'
60
+ subject.request.remote_ip '1.1.1.1'
61
+
62
+ subject.remote_permission.token.must_equal 'behappy'
63
+ subject.remote_permission.ip.must_equal '1.1.1.1'
64
+ end
65
+ end
@@ -0,0 +1,40 @@
1
+ require 'ixtlan/remote/model_helpers'
2
+ require 'active_support/core_ext/string'
3
+ describe Ixtlan::Remote::ModelHelpers do
4
+
5
+ subject { Object.send :include, Ixtlan::Remote::ModelHelpers }
6
+
7
+ it 'should pass through' do
8
+ subject.to_model("asd").must_equal "asd"
9
+ subject.to_model(:asd).must_equal :asd
10
+ end
11
+
12
+ it 'should get first key of hash' do
13
+ subject.to_model(:be_happy => []).must_equal :be_happy
14
+ subject.to_model(:be_happy => {}).must_equal :be_happy
15
+ end
16
+
17
+ it 'should get class' do
18
+ subject.to_model(String).must_equal String
19
+ subject.to_model(["dsa"]).must_equal String
20
+ subject.to_model(Object.new).must_equal Object
21
+ end
22
+
23
+ it 'should get underscored string' do
24
+ subject.to_model_underscore(StringIO).must_equal 'string_io'
25
+ subject.to_model_underscore(["dsa"]).must_equal 'string'
26
+ subject.to_model_underscore(Object.new).must_equal 'object'
27
+ subject.to_model_underscore(:be_happy => []).must_equal 'be_happy'
28
+ subject.to_model_underscore(:be_happy => {}).must_equal 'be_happy'
29
+ subject.to_model_underscore("asd").must_equal 'asd'
30
+ subject.to_model_underscore(:asd).must_equal 'asd'
31
+ end
32
+
33
+ it 'should get underscored singular' do
34
+ #subject.to_model_singular_underscore('women').must_equal 'woman'
35
+ #subject.to_model_singular_underscore(:men).must_equal 'man'
36
+ subject.to_model_singular_underscore('cars').must_equal 'car'
37
+ subject.to_model_singular_underscore(:cars).must_equal 'car'
38
+ end
39
+
40
+ end
@@ -0,0 +1,36 @@
1
+ require 'ixtlan/remote/model_helpers'
2
+ require 'active_support/core_ext/string'
3
+ describe Ixtlan::Remote::ModelHelpers do
4
+
5
+ subject { Object.send :include, Ixtlan::Remote::ModelHelpers }
6
+
7
+ it 'should pass through' do
8
+ subject.to_model("asd").must_equal "asd"
9
+ subject.to_model(:asd).must_equal :asd
10
+ end
11
+
12
+ it 'should get first key of hash' do
13
+ subject.to_model(:be_happy => []).must_equal :be_happy
14
+ end
15
+
16
+ it 'should get class' do
17
+ subject.to_model(String).must_equal String
18
+ subject.to_model(["dsa"]).must_equal String
19
+ subject.to_model(Object.new).must_equal Object
20
+ end
21
+
22
+ it 'should get underscored string' do
23
+ subject.to_model_underscore(StringIO).must_equal 'string_io'
24
+ subject.to_model_underscore(["dsa"]).must_equal 'string'
25
+ subject.to_model_underscore(Object.new).must_equal 'object'
26
+ subject.to_model_underscore(:be_happy => []).must_equal 'be_happy'
27
+ subject.to_model_underscore("asd").must_equal 'asd'
28
+ subject.to_model_underscore(:asd).must_equal 'asd'
29
+ end
30
+
31
+ it 'should get underscored singular' do
32
+ subject.to_model_singular_underscore('women').must_equal 'woman'
33
+ subject.to_model_singular_underscore(:men).must_equal 'man'
34
+ end
35
+
36
+ end
@@ -0,0 +1,36 @@
1
+ require 'ixtlan/remote/model_helpers'
2
+ require 'active_support/core_ext/string'
3
+ describe Ixtlan::Remote::ModelHelpers do
4
+
5
+ subject { Object.send :include, Ixtlan::Remote::ModelHelpers }
6
+
7
+ it 'should pass through' do
8
+ subject.to_model("asd").must_equal "asd"
9
+ subject.to_model(:asd).must_equal :asd
10
+ end
11
+
12
+ it 'should get first key of hash' do
13
+ subject.to_model(:be_happy => []).must_equal :be_happy
14
+ end
15
+
16
+ it 'should get class' do
17
+ subject.to_model(String).must_equal String
18
+ subject.to_model(["dsa"]).must_equal String
19
+ subject.to_model(Object.new).must_equal Object
20
+ end
21
+
22
+ it 'should get underscored string' do
23
+ subject.to_model_underscore(StringIO).must_equal 'string_io'
24
+ subject.to_model_underscore(["dsa"]).must_equal 'string'
25
+ subject.to_model_underscore(Object.new).must_equal 'object'
26
+ subject.to_model_underscore(:be_happy => []).must_equal 'be_happy'
27
+ subject.to_model_underscore("asd").must_equal 'asd'
28
+ subject.to_model_underscore(:asd).must_equal 'asd'
29
+ end
30
+
31
+ it 'should get underscored singular' do
32
+ subject.to_model_singular_underscore('women').must_equal 'woman'
33
+ subject.to_model_singular_underscore(:men).must_equal 'man'
34
+ end
35
+
36
+ end
@@ -0,0 +1,181 @@
1
+ require 'ixtlan/remote/resource'
2
+ require 'ixtlan/remote/server'
3
+ require 'active_support/core_ext/string'
4
+ require 'json'
5
+ class RestClientMock
6
+
7
+ def [](path)
8
+ @path = path
9
+ self
10
+ end
11
+
12
+ attr_reader :path
13
+ attr_accessor :response_payload
14
+
15
+ def response_payload( *args )
16
+ @response_payload
17
+ end
18
+
19
+ alias :get :response_payload
20
+ alias :post :response_payload
21
+ alias :put :response_payload
22
+ alias :delete :response_payload
23
+
24
+ end
25
+ class User
26
+
27
+ def initialize( args = {} )
28
+ @id = (args || {})['id'].to_i
29
+ @name = (args || {})['name']
30
+ end
31
+
32
+ attr_reader :id, :name
33
+
34
+ def attributes
35
+ {'id' => @id, 'name' => @name }
36
+ end
37
+ end
38
+ class ClientUser < User; end
39
+
40
+ describe Ixtlan::Remote::Resource do
41
+
42
+ subject { Ixtlan::Remote::Resource.new( rest_client, User ) }
43
+
44
+ let( :rest_client ) { ::RestClientMock.new }
45
+
46
+ describe 'create' do
47
+ [ [User], [:users], ["users"], ["admins", 1, User], ["admins/1", User], [ClientUser] ].each do |user|
48
+ user.push({:name => 'bla'})
49
+ it 'user without root' do
50
+
51
+ rest_client.response_payload = '{ "id": 1, "name": "bla" }'
52
+
53
+ u = subject.create( *user ).send_it
54
+ u.id.must_equal 1
55
+ u.name.must_equal 'bla'
56
+
57
+ u.class.must_equal User
58
+ rest_client.path.must_match /(.*\/)?users$/
59
+ end
60
+
61
+ it 'user with root' do
62
+
63
+ rest_client.response_payload = '{ "user": { "id": 1, "name": "bla" } }'
64
+
65
+ u = subject.create( *user ).send_it
66
+ u.id.must_equal 1
67
+ u.name.must_equal 'bla'
68
+
69
+ u.class.must_equal User
70
+ rest_client.path.must_match /(.*\/)?users$/
71
+ end
72
+ end
73
+ end
74
+
75
+ describe 'retrieve' do
76
+ [ [User.new('id' => 1)], [User], [:users], ["users"], ["admins", 1, User], ["admins/1", User], [ClientUser] ].each do |user|
77
+ it 'user without root' do
78
+
79
+ rest_client.response_payload = '{ "id": 1, "name": "bla" }'
80
+
81
+ uu = user.dup
82
+ uu.push( 1 )
83
+ u = subject.retrieve( *uu ).send_it
84
+ u.id.must_equal 1
85
+ u.name.must_equal 'bla'
86
+
87
+ u.class.must_equal User
88
+ rest_client.path.must_match /(.*\/)?users\/1$/
89
+ end
90
+
91
+ it 'users without root' do
92
+
93
+ rest_client.response_payload = '[ { "id": 1, "name": "bla" }, { "id": 2, "name": "blabla" } ]'
94
+
95
+ u = subject.retrieve( *user ).send_it
96
+ u.size.must_equal 2
97
+ u[0].id.must_equal 1
98
+ u[0].name.must_equal 'bla'
99
+ u[1].id.must_equal 2
100
+ u[1].name.must_equal 'blabla'
101
+
102
+ u[0].class.must_equal User
103
+ u[1].class.must_equal User
104
+ rest_client.path.must_match /(.*\/)?users$/
105
+ end
106
+
107
+ it 'user with root' do
108
+
109
+ rest_client.response_payload = '{ "user": { "id": 1, "name": "bla" } }'
110
+
111
+ uu = user.dup
112
+ uu.push( 1 )
113
+ u = subject.create( *uu ).send_it
114
+ u.id.must_equal 1
115
+ u.name.must_equal 'bla'
116
+
117
+ u.class.must_equal User
118
+ rest_client.path.must_match /(.*\/)?users\/1$/
119
+ end
120
+
121
+ it 'users with root' do
122
+
123
+ rest_client.response_payload = '[ { "user": { "id": 1, "name": "bla" } }, { "user": { "id": 2, "name": "blabla" } } ]'
124
+
125
+ u = subject.create( *user ).send_it
126
+ u.size.must_equal 2
127
+ u[0].id.must_equal 1
128
+ u[0].name.must_equal 'bla'
129
+ u[1].id.must_equal 2
130
+ u[1].name.must_equal 'blabla'
131
+
132
+ u[0].class.must_equal User
133
+ u[1].class.must_equal User
134
+ rest_client.path.must_match /(.*\/)?users$/
135
+ end
136
+ end
137
+ end
138
+
139
+ describe 'update' do
140
+ [ [User.new('id' => 1)], [User], [:users], ["users"], ["admins", 1, User], ["admins/1", User], [ClientUser] ].each do |user|
141
+ user.push( 1 )
142
+ user.push( {:name => 'buh'} )
143
+
144
+ it 'user without root' do
145
+
146
+ rest_client.response_payload = '{ "id": 1, "name": "bla" }'
147
+
148
+ u = subject.update( *user ).send_it
149
+ u.id.must_equal 1
150
+ u.name.must_equal 'bla'
151
+
152
+ u.class.must_equal User
153
+ rest_client.path.must_match /(.*\/)?users\/1$/
154
+ end
155
+
156
+ it "user with root #{user} " do
157
+
158
+ rest_client.response_payload = '{ "user": { "id": 1, "name": "blablabla" } }'
159
+
160
+ u = subject.update( *user ).send_it
161
+
162
+ u.id.must_equal 1
163
+ u.name.must_equal 'blablabla'
164
+ u.class.must_equal User
165
+ rest_client.path.must_match /(.*\/)?users\/1$/
166
+ end
167
+ end
168
+ end
169
+
170
+ describe 'delete' do
171
+ [ [User, 1], [:users,1], ["users",1], ["admins", 1, User, 1], ["admins/1", User, 1], [ClientUser, 1] ].each do |user|
172
+ it "user #{user.inspect}" do
173
+
174
+ subject.delete( *user ).send_it.must_be_nil
175
+
176
+ rest_client.path.must_match /(.*\/)?users\/1$/
177
+
178
+ end
179
+ end
180
+ end
181
+ end