rad_kit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/Rakefile +11 -0
  2. data/lib/components/kit.rb +16 -0
  3. data/lib/components/kit.yml +3 -0
  4. data/lib/components/models.rb +7 -0
  5. data/lib/kit/factories.rb +9 -0
  6. data/lib/kit/gems.rb +16 -0
  7. data/lib/kit/http_controller.rb +4 -0
  8. data/lib/kit/http_controller/authorized.rb +51 -0
  9. data/lib/kit/http_controller/localized.rb +13 -0
  10. data/lib/kit/kit.rb +29 -0
  11. data/lib/kit/models.rb +8 -0
  12. data/lib/kit/models/attachment_uploader.rb +15 -0
  13. data/lib/kit/models/attachments_uploader_helper.rb +79 -0
  14. data/lib/kit/models/authorized.rb +188 -0
  15. data/lib/kit/models/authorized_object.rb +167 -0
  16. data/lib/kit/models/default_permissions.yml +29 -0
  17. data/lib/kit/models/file_uploader.rb +26 -0
  18. data/lib/kit/models/micelaneous.rb +1 -0
  19. data/lib/kit/models/role.rb +88 -0
  20. data/lib/kit/models_after.rb +27 -0
  21. data/lib/kit/mongoid.rb +22 -0
  22. data/lib/kit/mongoid/rad_micelaneous.rb +36 -0
  23. data/lib/kit/mongoid/text_processor.rb +44 -0
  24. data/lib/kit/spec.rb +77 -0
  25. data/lib/kit/spec/items_controller_crud.rb +64 -0
  26. data/lib/kit/support.rb +14 -0
  27. data/lib/kit/support/string.rb +6 -0
  28. data/lib/kit/tasks.rb +18 -0
  29. data/lib/kit/text_utils.rb +43 -0
  30. data/lib/kit/text_utils/code_highlighter.rb +58 -0
  31. data/lib/kit/text_utils/custom_markdown.rb +90 -0
  32. data/lib/kit/text_utils/ensure_utf.rb +8 -0
  33. data/lib/kit/text_utils/github_flavoured_markdown.rb +32 -0
  34. data/lib/kit/text_utils/html_sanitizer.rb +89 -0
  35. data/lib/kit/text_utils/image_box.rb +35 -0
  36. data/lib/kit/text_utils/markup.rb +43 -0
  37. data/lib/kit/text_utils/processor.rb +25 -0
  38. data/lib/kit/text_utils/tag_shortcuts.rb +14 -0
  39. data/lib/kit/text_utils/truncate.rb +29 -0
  40. data/lib/kit/text_utils/truncator.rb +15 -0
  41. data/lib/kit/text_utils/urls.rb +13 -0
  42. data/readme.md +10 -0
  43. data/spec/controller/authorization_spec.rb +149 -0
  44. data/spec/controller/comments_spec.rb +54 -0
  45. data/spec/controller/items_spec.rb +45 -0
  46. data/spec/models/attachments_spec.rb +24 -0
  47. data/spec/models/attachments_spec/a.txt +1 -0
  48. data/spec/models/attachments_uploader_helper_spec.rb +108 -0
  49. data/spec/models/attachments_uploader_helper_spec/v1/a.txt +1 -0
  50. data/spec/models/attachments_uploader_helper_spec/v1/b.txt +1 -0
  51. data/spec/models/attachments_uploader_helper_spec/v2/a.txt +1 -0
  52. data/spec/models/authorization_spec.rb +77 -0
  53. data/spec/models/authorized_object_spec.rb +254 -0
  54. data/spec/models/comments_spec.rb +1 -0
  55. data/spec/models/item_spec.rb +51 -0
  56. data/spec/models/role_spec.rb +17 -0
  57. data/spec/models/tags_spec.rb +44 -0
  58. data/spec/models/uploader_spec.rb +37 -0
  59. data/spec/models/uploader_spec//321/204/320/260/320/270/314/206/320/273 /321/201 /320/277/321/200/320/276/320/261/320/265/320/273/320/260/320/274/320/270.txt" +1 -0
  60. data/spec/mongoid/basic_spec.rb +36 -0
  61. data/spec/spec_helper.rb +20 -0
  62. data/spec/spec_helper/controller.rb +9 -0
  63. data/spec/spec_helper/factories.rb +24 -0
  64. data/spec/spec_helper/user.rb +17 -0
  65. data/spec/utils/text_utils_spec.rb +280 -0
  66. metadata +232 -0
@@ -0,0 +1,167 @@
1
+ module Mongoid::AuthorizedObject
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ field :owner_name,
6
+ type: String,
7
+ default: lambda{rad.user? ? rad.user.name : nil},
8
+ protected: true
9
+ attr_protected :owner
10
+
11
+ field :collaborators,
12
+ type: Array,
13
+ default: [],
14
+ protected: true
15
+
16
+ # Contains the role and all upper roles. So complex becouse we need it in indexes.
17
+ field :viewers,
18
+ type: Array,
19
+ default: lambda{(
20
+ (rad.user? ? ['manager', "user:#{rad.user.name}"] : ['manager']) +
21
+ Array.wrap(rad.config.default_viewers)
22
+ ).uniq.sort},
23
+ protected: true
24
+
25
+ validates_presence_of :owner_name
26
+ validate :validate_viewers
27
+ validate :validate_collaborators
28
+ end
29
+
30
+ #
31
+ # Owner
32
+ #
33
+ def owner
34
+ return nil if owner_name.blank?
35
+ cache[:owner] ||= Models::User.by_name!(owner_name)
36
+ end
37
+
38
+ def owner= user
39
+ user.must_be.an Models::User
40
+ cache[:owner] = user
41
+ self.owner_name = user.name
42
+ user
43
+ end
44
+
45
+ # TODO3 update it later, MM uses public API to unmarshal object
46
+ # http://groups.google.com/group/mongomapper/browse_thread/thread/ab34457e0ba9c472#
47
+ def owner_name= name
48
+ owner_role = "user:#{name}"
49
+ old_owner_role = "user:#{owner_name}"
50
+
51
+ unless viewers.include? owner_role
52
+ viewers.delete old_owner_role
53
+ viewers << owner_role
54
+ viewers.sort!
55
+ end
56
+
57
+ # write_attribute :owner_name, name
58
+ super name
59
+ clear_cache
60
+ owner_name
61
+ end
62
+
63
+ #
64
+ # Viewers and Collaborators
65
+ #
66
+ def add_viewer role
67
+ role = role.to_s
68
+ should_be_valid_user_input_role role
69
+
70
+ return if viewers.include? role
71
+
72
+ roles = viewers
73
+ roles << role
74
+ roles = Role.denormalize_to_higher_roles roles
75
+ roles << 'manager' unless roles.include? 'manager'
76
+ self.viewers = roles.sort
77
+ viewers
78
+ end
79
+
80
+ def remove_viewer role
81
+ role = role.to_s
82
+ should_be_valid_user_input_role role
83
+
84
+ return unless viewers.include? role
85
+
86
+ roles = viewers
87
+ Role.denormalize_to_higher_roles([role]).each do |r|
88
+ roles.delete r
89
+ end
90
+ roles << 'manager' unless roles.include? 'manager'
91
+ self.viewers = roles.sort
92
+
93
+ remove_collaborator role
94
+
95
+ viewers
96
+ end
97
+
98
+ def minor_viewers
99
+ unless minor_viewers = cache[:minor_viewers]
100
+ viewers = self.viewers.clone
101
+ viewers.delete 'manager'
102
+ minor_viewers = Role.minor_roles viewers
103
+ cache[:minor_viewers] = minor_viewers
104
+ end
105
+ minor_viewers
106
+ end
107
+
108
+ def add_collaborator role
109
+ role = role.to_s
110
+ should_be_valid_user_input_role role
111
+ return if collaborators.include? role
112
+ collaborators = self.collaborators.clone
113
+ collaborators << role
114
+ self.collaborators = collaborators
115
+
116
+ add_viewer role
117
+
118
+ collaborators
119
+ end
120
+
121
+ def remove_collaborator role
122
+ role = role.to_s
123
+ should_be_valid_user_input_role role
124
+ collaborators.delete role
125
+ collaborators
126
+ end
127
+
128
+ def normalized_collaborators
129
+ unless normalized_collaborators = cache[:normalized_collaborators]
130
+ normalized_collaborators = Role.denormalize_to_higher_roles collaborators
131
+ normalized_collaborators << "user:#{owner_name}"
132
+ normalized_collaborators.sort!
133
+ cache[:normalized_collaborators] = normalized_collaborators
134
+ end
135
+ normalized_collaborators
136
+ end
137
+
138
+
139
+ #
140
+ # Special Permissions
141
+ #
142
+ def able_view? user
143
+ user.roles.any?{|role| viewers.include? role}
144
+ end
145
+
146
+ def able_update? user
147
+ user.roles.any?{|role| normalized_collaborators.include? role}
148
+ end
149
+
150
+ protected
151
+ def should_be_valid_user_input_role role
152
+ role.must_not == 'manager'
153
+ role.must_not == "user:#{owner_name}"
154
+ end
155
+
156
+ def validate_viewers
157
+ viewers.must == viewers.uniq
158
+
159
+ viewers.must.include 'manager' # always
160
+ viewers.must.include "user:#{owner_name}"
161
+ end
162
+
163
+ def validate_collaborators
164
+ collaborators.must_not.include "user:#{owner_name}"
165
+ end
166
+
167
+ end
@@ -0,0 +1,29 @@
1
+ # General
2
+ view: [] #anonymous, registered
3
+
4
+ # Administration
5
+ administration: [admin]
6
+
7
+ # Authorization
8
+ add_admin_role: []
9
+ add_custom_role: [manager]
10
+ add_manager_role: []
11
+ add_member_role: [manager]
12
+ remove_admin_role: []
13
+ remove_custom_role: [manager]
14
+ remove_manager_role: []
15
+ remove_member_role: [manager]
16
+ update_access: [manager, owner]
17
+
18
+ # User Management
19
+ update_profile: [owner]
20
+
21
+ # Items
22
+ create: [member]
23
+ # update: [manager, owner]
24
+ destroy: [manager, owner]
25
+
26
+ # Comments
27
+ create_comment: [registered]
28
+ update_comment: [manager, owner]
29
+ destroy_comment: [manager, owner]
@@ -0,0 +1,26 @@
1
+ require 'carrierwave/processing/mini_magick'
2
+
3
+ class Models::FileUploader < CarrierWave::Uploader::Base
4
+ include CarrierWave::MiniMagick
5
+
6
+ storage rad.config.fs_type
7
+
8
+ # def sanitize_regexp
9
+ # /[^[:word:]\.\-\+\s_]/i
10
+ # end
11
+
12
+ def file_path
13
+ "#{rad.config.fs_prefix}/system/#{model.class.model_name.underscore}/#{model.id}"
14
+ end
15
+
16
+ def store_dir
17
+ "#{root}#{file_path}"
18
+ end
19
+
20
+ def extension_white_list
21
+ [/.*/]
22
+ end
23
+
24
+ def cache_dir; rad.config.fs_cache_path end
25
+ def root; rad.config.fs_path end
26
+ end
@@ -0,0 +1 @@
1
+ STRONG_NAME = /\A[a-z_][a-z_0-9]*\Z/
@@ -0,0 +1,88 @@
1
+ class Role
2
+ ORDERED_ROLES = %w{manager member user}.freeze
3
+ SYSTEM_ROLES = %w{admin anonymous manager member owner registered user}.sort.freeze
4
+ PRESERVED_USER_NAMES = SYSTEM_ROLES
5
+
6
+ class << self
7
+
8
+ def normalize_roles roles
9
+ ordinary_roles, ordered_roles = split roles
10
+ ordinary_roles << lower_role(ordered_roles)
11
+ ordinary_roles.sort
12
+ end
13
+
14
+ def denormalize_to_higher_roles roles
15
+ ordinary_roles, ordered_roles = split roles
16
+ ordinary_roles.push *higher_roles(lower_role(ordered_roles))
17
+ ordinary_roles.sort
18
+ end
19
+
20
+ def denormalize_to_lower_roles roles
21
+ ordinary_roles, ordered_roles = split roles
22
+ ordinary_roles.push *lower_roles(higher_role(ordered_roles))
23
+ ordinary_roles.sort
24
+ end
25
+
26
+ def higher_role roles
27
+ ORDERED_ROLES.each do |role|
28
+ return role if roles.include? role
29
+ end
30
+ nil
31
+ end
32
+
33
+ def lower_role roles
34
+ ORDERED_ROLES.reverse.each do |role|
35
+ return role if roles.include? role
36
+ end
37
+ nil
38
+ end
39
+
40
+ def major_roles roles
41
+ major_roles = roles.select{|role| !SYSTEM_ROLES.include?(role)}
42
+ if higher_role = higher_role(roles)
43
+ major_roles << higher_role
44
+ end
45
+ major_roles.sort
46
+ end
47
+
48
+ def minor_roles roles
49
+ minor_roles = roles.select{|role| !SYSTEM_ROLES.include?(role)}
50
+ if lower_role = lower_role(roles)
51
+ minor_roles << lower_role
52
+ end
53
+ minor_roles.sort
54
+ end
55
+
56
+ protected
57
+ def split roles
58
+ ordinary_roles = []
59
+ ordered_roles = []
60
+
61
+ roles.collect do |role|
62
+ if ORDERED_ROLES.include? role
63
+ ordered_roles << role
64
+ else
65
+ ordinary_roles << role
66
+ end
67
+ end
68
+
69
+ [ordinary_roles, ordered_roles]
70
+ end
71
+
72
+ def lower_roles role
73
+ return [] if role.nil?
74
+
75
+ role.must_be.in ORDERED_ROLES
76
+ index = ORDERED_ROLES.index role
77
+ ORDERED_ROLES[index..-1]
78
+ end
79
+
80
+ def higher_roles role
81
+ return [] if role.nil?
82
+
83
+ role.must_be.in ORDERED_ROLES
84
+ index = ORDERED_ROLES.index role
85
+ ORDERED_ROLES[0..index]
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,27 @@
1
+ # use database config if provided
2
+ if rad.models.config
3
+ b = lambda do
4
+ Mongoid.configure do |config|
5
+ config.logger = rad.logger
6
+ end
7
+ Mongoid.from_hash rad.models.config
8
+ end
9
+
10
+ # hiding MongoDB connecting messages
11
+ rad.logger.respond_to?(:silence) ? rad.logger.silence(&b) : b.call
12
+ end
13
+
14
+
15
+ %w(
16
+ micelaneous
17
+ role
18
+ authorized
19
+ authorized_object
20
+ file_uploader
21
+ attachments_uploader_helper
22
+ attachment_uploader
23
+ ).each{|n| require "kit/models/#{n}"}
24
+
25
+ Mongoid::Document.class_eval do
26
+ include Mongoid::AttachmentsUploaderHelper
27
+ end
@@ -0,0 +1,22 @@
1
+ require 'mongoid_misc'
2
+ require 'carrierwave_ext'
3
+ require 'rad'
4
+
5
+ #
6
+ # Attribute protection
7
+ #
8
+ Mongoid::Document.included do
9
+ attr_protected :id, :_id, :_type, :created_at, :updated_at
10
+ end
11
+
12
+ module Models
13
+ end
14
+
15
+ %w(
16
+ text_processor
17
+ rad_micelaneous
18
+ ).each{|n| require "kit/mongoid/#{n}"}
19
+
20
+ (rad.extension(:mm_plugins){[]} + [Mongoid::RadMicelaneous]).each do |plugin|
21
+ Mongoid::Document.include plugin
22
+ end
@@ -0,0 +1,36 @@
1
+ module Mongoid::RadMicelaneous
2
+ extend ActiveSupport::Concern
3
+
4
+ delegate :t, to: I18n
5
+
6
+ def to_rson options = {}
7
+ with_errors = if options.include?('errors')
8
+ options.delete 'errors'
9
+ elsif options.include?(:errors)
10
+ options.delete :errors
11
+ else
12
+ true
13
+ end
14
+
15
+ # standard MongoMaper as_json conversion
16
+ hash = as_json(options)
17
+
18
+ # MongoMaper fix
19
+ hash['id'] = hash.delete('_id').to_s if hash.include? '_id'
20
+
21
+ # adding errors
22
+ if with_errors
23
+ errors = {}
24
+ errors.each do |name, list|
25
+ errors[name.to_s] = list
26
+ end
27
+ hash['errors'] = errors unless errors.empty?
28
+ end
29
+
30
+ hash
31
+ end
32
+
33
+ module ClassMethods
34
+ delegate :t, to: I18n
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ module Mongoid::TextProcessor
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ def markup_field attr_name, opt = {}
6
+ attr_name = attr_name.to_s
7
+ opt = opt.to_openobject
8
+ original_attr_name = "original_#{attr_name}"
9
+
10
+ field original_attr_name, type: String, default: ''
11
+ field attr_name, type: String, protected: true, default: '' unless fields.include? attr_name
12
+
13
+ validates_presence_of attr_name, original_attr_name if opt.required?
14
+
15
+ alias_method "#{attr_name}_without_markup=", "#{attr_name}="
16
+ alias_method "#{original_attr_name}_without_markup=", "#{original_attr_name}="
17
+
18
+ define_method "#{attr_name}=" do |value|
19
+ send "#{original_attr_name}_without_markup=", value
20
+ send "#{attr_name}_without_markup=", value
21
+ end
22
+
23
+ define_method "#{original_attr_name}=" do |value|
24
+ send "#{original_attr_name}_without_markup=", value
25
+ send "#{attr_name}_without_markup=", Rad::TextUtils.markup(value)
26
+ end
27
+
28
+ define_method "#{attr_name}_as_text" do
29
+ value = send(attr_name)
30
+ return "" if value.blank?
31
+ Nokogiri::XML(value).content
32
+ end
33
+
34
+ ce_method_name = "copy_errors_for_#{attr_name}"
35
+ define_method ce_method_name do
36
+ if !errors.include?(original_attr_name) and errors.include?(attr_name)
37
+ errors.add original_attr_name, errors[attr_name]
38
+ end
39
+ end
40
+ after_validation ce_method_name
41
+ end
42
+ end
43
+
44
+ end