rapid 0.0.1

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