rapid 0.0.1

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 (60) hide show
  1. data/Rakefile +66 -0
  2. data/lib/rad/http_controller/acts_as/authenticated.rb +131 -0
  3. data/lib/rad/http_controller/acts_as/authenticated_master_domain.rb +119 -0
  4. data/lib/rad/http_controller/acts_as/authorized.rb +83 -0
  5. data/lib/rad/http_controller/acts_as/localized.rb +27 -0
  6. data/lib/rad/http_controller/acts_as/multitenant.rb +53 -0
  7. data/lib/rad/http_controller/helpers/service_mix_helper.rb +50 -0
  8. data/lib/rad/http_controller.rb +15 -0
  9. data/lib/rad/lib/text_utils.rb +334 -0
  10. data/lib/rad/locales/en.yml +80 -0
  11. data/lib/rad/locales/ru.yml +83 -0
  12. data/lib/rad/locales.rb +2 -0
  13. data/lib/rad/models/account.rb +88 -0
  14. data/lib/rad/models/default_permissions.yml +26 -0
  15. data/lib/rad/models/micelaneous.rb +1 -0
  16. data/lib/rad/models/role.rb +88 -0
  17. data/lib/rad/models/secure_token.rb +33 -0
  18. data/lib/rad/models/space.rb +184 -0
  19. data/lib/rad/models/user.rb +158 -0
  20. data/lib/rad/models.rb +41 -0
  21. data/lib/rad/mongo_mapper/acts_as/authenticated_by_open_id.rb +29 -0
  22. data/lib/rad/mongo_mapper/acts_as/authenticated_by_password.rb +120 -0
  23. data/lib/rad/mongo_mapper/acts_as/authorized.rb +197 -0
  24. data/lib/rad/mongo_mapper/acts_as/authorized_object.rb +171 -0
  25. data/lib/rad/mongo_mapper/multitenant.rb +34 -0
  26. data/lib/rad/mongo_mapper/rad_micelaneous.rb +43 -0
  27. data/lib/rad/mongo_mapper/space_keys.rb +62 -0
  28. data/lib/rad/mongo_mapper/text_processor.rb +47 -0
  29. data/lib/rad/mongo_mapper.rb +20 -0
  30. data/lib/rad/paperclip/callbacks.rb +40 -0
  31. data/lib/rad/paperclip/extensions.rb +64 -0
  32. data/lib/rad/paperclip/integration.rb +165 -0
  33. data/lib/rad/paperclip/mime.rb +5 -0
  34. data/lib/rad/paperclip/validations.rb +64 -0
  35. data/lib/rad/paperclip.rb +11 -0
  36. data/lib/rad/spec/controller.rb +51 -0
  37. data/lib/rad/spec/model/factories.rb +65 -0
  38. data/lib/rad/spec/model.rb +85 -0
  39. data/lib/rad/spec/rem_helper.rb +145 -0
  40. data/lib/rad/spec.rb +4 -0
  41. data/lib/rad/tasks/backup.rake +64 -0
  42. data/lib/rad/tasks/initialize.rake +35 -0
  43. data/lib/rad.rb +32 -0
  44. data/readme.md +3 -0
  45. data/spec/controller/authorization_spec.rb +146 -0
  46. data/spec/controller/helper.rb +14 -0
  47. data/spec/lib/helper.rb +7 -0
  48. data/spec/lib/text_utils_spec.rb +238 -0
  49. data/spec/models/authorization_spec.rb +93 -0
  50. data/spec/models/authorized_object_spec.rb +258 -0
  51. data/spec/models/file_audit_spec/100.txt +1 -0
  52. data/spec/models/file_audit_spec/302.txt +3 -0
  53. data/spec/models/file_audit_spec.rb +168 -0
  54. data/spec/models/helper.rb +11 -0
  55. data/spec/models/space_key_spec.rb +68 -0
  56. data/spec/models/user_spec.rb +80 -0
  57. data/spec/mongo_mapper/basic_spec.rb +41 -0
  58. data/spec/mongo_mapper/helper.rb +10 -0
  59. data/spec/spec.opts +4 -0
  60. metadata +138 -0
data/lib/rad.rb ADDED
@@ -0,0 +1,32 @@
1
+ # crystal
2
+ require 'crystal_ext/profiles/web_ext'
3
+
4
+ # crystal plugins
5
+ require 'crystal_jquery'
6
+ require 'common_interface'
7
+
8
+ # gems
9
+ %w(
10
+ mongo_mapper
11
+ nokogiri
12
+ bluecloth
13
+ sanitize
14
+ state_machine
15
+ rack
16
+ ).each{|n| gem n}
17
+ # paperclip
18
+
19
+ #
20
+ # rad
21
+ #
22
+
23
+ # lib
24
+ module Rad
25
+ autoload :TextUtils, 'rad/lib/text_utils'
26
+ end
27
+
28
+ require 'rad/locales'
29
+ crystal.after :environment do
30
+ require 'rad/models'
31
+ end
32
+ require 'rad/http_controller'
data/readme.md ADDED
@@ -0,0 +1,3 @@
1
+ # Rapid Application Development platform for Crystal framework
2
+
3
+ [add docs]
@@ -0,0 +1,146 @@
1
+ require "#{File.expand_path(File.dirname(__FILE__))}/helper"
2
+
3
+ describe "Authorizations" do
4
+ with_environment
5
+ with_http
6
+ with_rad_model
7
+
8
+ before :all do
9
+ load 'crystal_ext/profiles/web_ext.rb'
10
+
11
+ permissions = {
12
+ 'call_controller_level' => [],
13
+ 'call_business_logic_level' => [],
14
+ 'call_with_owner' => []
15
+ }
16
+ Space.stub!(:permissions).and_return(permissions)
17
+
18
+ class ::AuthorizationController
19
+ inherit Crystal::HttpController
20
+
21
+ acts_as_authorized
22
+
23
+ require_permission :call_controller_level, :only => :controller_level
24
+
25
+ def unprotected
26
+ render_ok
27
+ end
28
+
29
+ def controller_level
30
+ render_ok
31
+ end
32
+
33
+ def business_logic_level
34
+ require_permission :call_business_logic_level
35
+ render_ok
36
+ end
37
+
38
+ def with_owner
39
+ require_permission :call_with_owner, owned_object
40
+ render_ok
41
+ end
42
+
43
+ def with_owner_controller_level
44
+ render_ok
45
+ end
46
+ require_permission :call_with_owner, :only => :with_owner_controller_level do
47
+ owned_object
48
+ end
49
+
50
+ protected
51
+ def owned_object
52
+ @@owned_object
53
+ end
54
+
55
+ def self.owned_object= o
56
+ @@owned_object = o
57
+ end
58
+ end
59
+
60
+ I18n.locale = :en
61
+ end
62
+
63
+ after :all do
64
+ remove_constants %w(AuthorizationController)
65
+ end
66
+
67
+ before :each do
68
+ AuthorizationController.owned_object = nil
69
+
70
+ @user = User.new
71
+ User.stub!(:current).and_return(@user)
72
+ end
73
+
74
+ def raise_authorization_error
75
+ raise_error(UserError, /Access Denied/)
76
+ end
77
+
78
+ it "should allow to call unprotected methods" do
79
+ wcall('/authorization_controller/unprotected')
80
+ response.body.should == "ok"
81
+ end
82
+
83
+ it "should allow declarative authorization at controller level" do
84
+ @user.stub!(:can?).and_return(false)
85
+ lambda{
86
+ wcall '/authorization_controller/controller_level'
87
+ }.should raise_authorization_error
88
+ # response.should be_redirect
89
+
90
+ @user.stub!(:can?).and_return(true)
91
+ wcall '/authorization_controller/controller_level'
92
+ response.body.should == "ok"
93
+ end
94
+
95
+ it "should allow declarative authorization at business logic level" do
96
+ @user.stub!(:can?).and_return(false)
97
+ lambda{
98
+ wcall '/authorization_controller/business_logic_level'
99
+ }.should raise_authorization_error
100
+ # response.should be_redirect
101
+
102
+ @user.stub!(:can?).and_return(true)
103
+ wcall '/authorization_controller/business_logic_level'
104
+ response.body.should == "ok"
105
+ end
106
+
107
+ it "should use owner if provided" do
108
+ @user.stub!(:can?){false}
109
+ lambda{
110
+ wcall '/authorization_controller/with_owner'
111
+ }.should raise_authorization_error
112
+ # response.should be_redirect
113
+
114
+
115
+ o = Object.new
116
+ o.stub!(:owner_name){@user.name}
117
+ AuthorizationController.owned_object = o
118
+
119
+ @user.stub!(:can?) do |operation, object|
120
+ object and object.owner_name == @user.name
121
+ end
122
+
123
+ wcall '/authorization_controller/with_owner'
124
+ response.body.should == "ok"
125
+ end
126
+
127
+ it "should use owner if provided (action level)" do
128
+ @user.stub!(:can?){false}
129
+ lambda{
130
+ wcall '/authorization_controller/with_owner_controller_level'
131
+ }.should raise_authorization_error
132
+ # response.should be_redirect
133
+
134
+
135
+ o = Object.new
136
+ o.stub!(:owner_name){@user.name}
137
+ AuthorizationController.owned_object = o
138
+
139
+ @user.stub!(:can?) do |operation, object|
140
+ object and object.owner_name == @user.name
141
+ end
142
+
143
+ wcall '/authorization_controller/with_owner_controller_level'
144
+ response.body.should == "ok"
145
+ end
146
+ end
@@ -0,0 +1,14 @@
1
+ dir = File.expand_path(File.dirname(__FILE__))
2
+ lib_dir = File.expand_path("#{dir}/../../../lib")
3
+ $LOAD_PATH << lib_dir unless $LOAD_PATH.include? lib_dir
4
+
5
+ require 'crystal_ext/profiles/web_ext_require'
6
+
7
+
8
+ require 'mongo_mapper'
9
+ require 'mongo_mapper_ext'
10
+ require 'rad/http_controller'
11
+
12
+
13
+ require 'crystal/spec'
14
+ require 'rad/spec'
@@ -0,0 +1,7 @@
1
+ dir = File.expand_path(File.dirname(__FILE__))
2
+ lib_dir = File.expand_path("#{dir}/../../../../lib")
3
+ $LOAD_PATH << lib_dir unless $LOAD_PATH.include? lib_dir
4
+
5
+ require 'spec_ext'
6
+
7
+ require 'crystal/support'
@@ -0,0 +1,238 @@
1
+ require "#{File.expand_path(File.dirname(__FILE__))}/helper"
2
+
3
+ require 'rad/lib/text_utils.rb'
4
+
5
+ describe "TextUtils" do
6
+ def to_doc markup
7
+ Nokogiri::HTML(to_html(markup))
8
+ end
9
+
10
+ def to_html markup
11
+ TextUtils.markup(markup)
12
+ end
13
+
14
+ ::Nokogiri::XML::Node.class_eval do
15
+ def should_be_equal_to attributes
16
+ attributes.stringify_keys!
17
+ self.content.should == content if content = attributes.delete('content')
18
+
19
+ attributes.each do |attr_name, value|
20
+ self[attr_name].to_s.should == value.to_s
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "MarkdDown" do
26
+ it "should do basic markup" do
27
+ doc = to_doc "**text**"
28
+ doc.css("p b, p strong").first.should_be_equal_to :content => 'text'
29
+ end
30
+
31
+ it "should guess urls" do
32
+ doc = to_doc "This is a http://www.some.com/some link"
33
+ doc.content.strip.should == "This is a http://www.some.com/some link"
34
+ doc.css("p a").first.should_be_equal_to :href => "http://www.some.com/some"
35
+
36
+ # from error
37
+ doc = to_doc "http://www.some.com/some"
38
+ doc.content.strip.should == "http://www.some.com/some"
39
+ doc.css("p a").first.should_be_equal_to :href => "http://www.some.com/some"
40
+
41
+ # from error
42
+ # http://mastertalk.ru/topic111478.html
43
+ end
44
+
45
+ it "should allow 'a' elements" do
46
+ html = <<HTML
47
+ <a href="http://www.some.com/some">Absolute Link</a>
48
+ <a href="/some">Relative Link</a>
49
+ HTML
50
+
51
+ doc = to_doc html
52
+ doc.css("a").first[:href].should == "http://www.some.com/some"
53
+ doc.css("a").last[:href].should == "/some"
54
+ end
55
+
56
+ it "should embed YouTube Videos" do
57
+ html =<<HTML
58
+ <object width="425" height="344">
59
+ <param name="movie" value="http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&"></param>
60
+ <param name="allowFullScreen" value="true"></param>
61
+ <param name="allowscriptaccess" value="always"></param>
62
+ <embed src="http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
63
+ </object>
64
+ HTML
65
+
66
+ doc = to_doc html
67
+ obj = doc.css("object").first.should_be_equal_to :width => 425, :height => 344
68
+ p1, p2, p3, embed = doc.css("object *")
69
+ p1.should_be_equal_to :name => "movie", :value => "http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&"
70
+ p2.should_be_equal_to :name => "allowFullScreen", :value => "true"
71
+ p3.should_be_equal_to :name => "allowscriptaccess", :value => "always"
72
+ embed.should_be_equal_to :src => "http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&",
73
+ :type => "application/x-shockwave-flash", :allowscriptaccess => "always",
74
+ :allowfullscreen => "true", :width => "425", :height => "344"
75
+ end
76
+
77
+ it "should skip empty paragraphs" do
78
+ html = "line 1\n\nline 2\n\n\n\nline 3"
79
+ to_html(html).should =~ /<p> line 1<\/p>\n<p>line 2<\/p>\n<p>line 3 <\/p>.?/
80
+ end
81
+
82
+ it "should convert \n to <br/>" do
83
+ to_doc("foo\nbar").css('br').size.should == 1
84
+ end
85
+
86
+ it "should not touch single underscores inside words" do
87
+ to_html("foo_bar").should include("foo_bar")
88
+ end
89
+
90
+ it "should works with unicode" do
91
+ html = %{Юникод <a href="http://www.some.com/" class="_image_box">Юникод</a>}
92
+ doc = to_doc html
93
+ doc.css('p').first.content.should =~ /Юникод/
94
+ doc.css('p a').first.should_be_equal_to :href => "http://www.some.com/", :class => "_image_box", :content => "Юникод"
95
+ end
96
+
97
+ it 'should allow class and rel attribute' do
98
+ html = %{<a href="http://www.some.com/" class="_image_box" rel="nofollow">Some</a>}
99
+ doc = to_doc html
100
+ doc.css('a').first.should_be_equal_to :href => "http://www.some.com/", :class => "_image_box", :rel => "nofollow"
101
+ end
102
+
103
+ it "should allow image inside of link" do
104
+ html = <<HTML
105
+ <a rel="article_images" class="_image_box" href="/some_image">
106
+ <img src="/some_image"></img>
107
+ </a>
108
+ HTML
109
+
110
+ doc = to_doc html
111
+ doc.css('a').first.should_be_equal_to :href => "/some_image", :class => "_image_box"
112
+ doc.css('a img').first.should_be_equal_to :src => "/some_image"
113
+ end
114
+
115
+ it "should use simplifyed syntax for image boxes (!![img_thumb] => [![img_thumb]][img_full_version])" do
116
+ html = <<HTML
117
+ !![img]
118
+ ![img]
119
+
120
+ !![img_2]
121
+ ![img_2]
122
+
123
+ [img]: /some_prefix/image_name.png
124
+ [img_2]: /some_prefix/image_name2.icon.png
125
+ HTML
126
+
127
+ doc = to_doc html
128
+ doc.css('a').first.should_be_equal_to :href => "/some_prefix/image_name.png"
129
+ doc.css('a img').first.should_be_equal_to :src => "/some_prefix/image_name.thumb.png"
130
+
131
+ doc.css('a').last.should_be_equal_to :href => "/some_prefix/image_name2.png"
132
+ doc.css('a img').last.should_be_equal_to :src => "/some_prefix/image_name2.icon.png"
133
+
134
+ doc.css('img').size.should == 4
135
+ end
136
+
137
+ it "simplifyed syntax for image boxes should be robust (from error)" do
138
+ html = "!![img] " # without resolved reference
139
+ to_html(html)
140
+ lambda{to_html(html)}.should_not raise_error
141
+ end
142
+
143
+ it "should create teaser from text" do
144
+ text = %{Hi there, I have a page that will list news articles}
145
+ TextUtils.truncate(text, 20).should == "Hi there, I have a ..."
146
+ end
147
+
148
+ it "should create teaser from html" do
149
+ text = %{Hi <div><b>there</b>, I have a page that will list news articles</div>}
150
+ TextUtils.truncate(text, 20).should == "Hi there, I have a ..."
151
+
152
+ TextUtils.truncate(%{a<br/>b}, 20).should == "a b" # from error
153
+ end
154
+
155
+ it "embed metaweb.com wiget" do
156
+ html = <<HTML
157
+ <div itemtype="http://www.freebase.com/id/computer/software" itemid="http://www.freebase.com/id/en/google_web_toolkit" itemscope="" style="border: 0pt none; outline: 0pt none; padding: 0pt; margin: 0pt; position: relative;" id="fbtb-6ffc2545598340cbbc7945f43ebd45de" class="fb-widget">
158
+ <iframe frameborder="0" scrolling="no" src="http://www.freebase.com/widget/topic?track=topicblocks_homepage&amp;mode=content&amp;id=%2Fen%2Fgoogle_web_toolkit" style="height: 285px; width: 413px; border: 0pt none; outline: 0pt none; padding: 0pt; margin: 0pt;" classname="fb-widget-iframe" allowtransparency="true" class=" "></iframe>
159
+ <script defer="" type="text/javascript" src="http://freebaselibs.com/static/widgets/2/widget.js"></script>
160
+ </div>
161
+ HTML
162
+
163
+ text = "{metaweb:google_web_toolkit}"
164
+ to_html(text).should include(html)
165
+ end
166
+
167
+ it "should correctly insert newline (from error)" do
168
+ html = <<HTML
169
+ ![img] Open Design.
170
+ http://oomps.com
171
+
172
+ [img]: /some_link
173
+ HTML
174
+
175
+ to_doc(html).css('br').size.should == 1
176
+ end
177
+
178
+ it "clear div" do
179
+ html = "[clear]"
180
+
181
+ doc = to_doc html
182
+ doc.css('div.clear').size.should == 1
183
+ end
184
+
185
+ it "space div" do
186
+ html = "[space]"
187
+
188
+ doc = to_doc html
189
+ doc.css('div.space').size.should == 1
190
+ end
191
+
192
+ it "should correctly guess links (from error)" do
193
+ to_doc("http://some_domain.com http://some_domain.com").css('a').size == 2
194
+ end
195
+
196
+ it "should leave existing links intact" do
197
+ doc = to_doc(%{<a href="http://some_domain.com">http://some_domain.com</a>})
198
+ doc.css('a').size.should == 1
199
+ doc.css('a').first['href'].should == "http://some_domain.com"
200
+ end
201
+
202
+ it "should leave existing links intact" do
203
+ md = %{\
204
+ [Download Page][dl]
205
+ [dl]: http://www.mozilla.org/products/firefox/}
206
+
207
+ to_doc(md).css('a').first['href'].should == 'http://www.mozilla.org/products/firefox/'
208
+ end
209
+
210
+ it "should allow div with any classes (from error)" do
211
+ html = %{<div class="col3 left"><a href='#'>text</a></div>}
212
+ to_doc(html).css("div.col3.left a").size.should == 1
213
+ end
214
+
215
+ it "should apply markup inside of html elements (from error)" do
216
+ html = <<HTML
217
+ <div class='right'>
218
+ ![img]
219
+ </div>
220
+
221
+ [img]: /some_link
222
+ HTML
223
+
224
+ to_doc(html).css('.right img').size.should == 1
225
+ end
226
+
227
+ it "shouldn't create newline after > sign (from error)" do
228
+ html = %{\
229
+ <div>text</div>
230
+ text}
231
+ to_doc(html).css('br').size.should == 0
232
+ end
233
+
234
+ it "shouldn't add empty <p> before first line (from error)" do
235
+ to_html("<span>text</span>text").should_not =~ /<p>\s*<\/p>/
236
+ end
237
+ end
238
+ end
@@ -0,0 +1,93 @@
1
+ require "#{File.expand_path(File.dirname(__FILE__))}/helper"
2
+
3
+ describe "Authorization" do
4
+ with_rad_model
5
+
6
+ before :each do
7
+ set_default_space
8
+ end
9
+
10
+ describe "Roles" do
11
+ it "normalization" do
12
+ Role.normalize_roles(%w{manager member specific_role user:user1}).should == %w{member specific_role user:user1}
13
+ end
14
+
15
+ it "denormalization to higher roles" do
16
+ Role.denormalize_to_higher_roles(%w{member specific_role user:user1}).should == %w{manager member specific_role user:user1}
17
+ end
18
+
19
+ it "denormalization to lower roles" do
20
+ Role.denormalize_to_lower_roles(%w{member specific_role user:user1}).should == %w{member specific_role user user:user1}
21
+ end
22
+
23
+ it "user should have it's name in roles" do
24
+ user = Factory.build :user, :name => 'some_name'
25
+ user.roles.include?('user:some_name').should be_true
26
+ end
27
+
28
+ it ":anonymous, :registered, :user roles" do
29
+ anonymous = Factory.build :anonymous
30
+ anonymous.roles.should == %w{anonymous user user:anonymous}
31
+
32
+ user = Factory.build :user, :name => 'name'
33
+ user.roles.should == %w{registered user user:name}
34
+
35
+ admin = Factory.build :admin, :name => 'john'
36
+ admin.roles.should == %w{admin manager member registered user user:john}
37
+ end
38
+
39
+ it "all managers should also have the member role, always" do
40
+ user = Factory.build :manager, :name => 'john'
41
+ user.roles.should == %w{manager member registered user user:john}
42
+ end
43
+
44
+ it "handy methods" do
45
+ u = User.anonymous
46
+ u.roles.anonymous?.should be_true
47
+ u.roles.registered?.should be_false
48
+ u.roles.has?(:anonymous).should be_true
49
+ u.should have_role(:anonymous)
50
+ end
51
+
52
+ it "add_role" do
53
+ u = Factory.create :member
54
+ u.should_not have_role('manager')
55
+ u.add_role :manager
56
+ u.save!
57
+ u.reload
58
+ u.should have_role('manager')
59
+ end
60
+
61
+ it "remove_role" do
62
+ u = Factory.create :manager
63
+ u.remove_role :member
64
+ u.save!
65
+ u.reload
66
+ u.should_not have_role('manger')
67
+ u.should_not have_role('member')
68
+ end
69
+
70
+ it "should add also all lover roles" do
71
+ u = Factory.create :user
72
+ u.roles.should_not include('member')
73
+ u.add_role :manager
74
+ u.roles.should include('member')
75
+ end
76
+
77
+ it "special case, admin role" do
78
+ u = Factory.create :user
79
+ u.should_not have_role('manager')
80
+ u.add_role :admin
81
+ u.save!
82
+ u.reload
83
+ u.should have_role('admin')
84
+ u.should have_role('manager')
85
+ end
86
+
87
+ it "major_roles" do
88
+ u = Factory.create :member, :name => 'aname'
89
+ u.add_role :director
90
+ u.major_roles.should == %w{director member user:aname}
91
+ end
92
+ end
93
+ end