Module: Zena::Acts::SecureNode::InstanceMethods
- Includes:
- RubyLess
- Defined in:
- lib/zena/acts/secure_node.rb
Instance Method Summary collapse
-
#can_drive?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
Can alter node (move around, name, rwp groups, etc).
-
#can_drive_was_true?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
‘can_drive?’ before attribute change.
-
#can_read?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
people who can read: * super user * members of
read_group
if the node is published and the current date is greater or equal to the publication date * members ofwrite_group
. -
#can_see_redactions?(ugps = visitor.group_ids) ⇒ Boolean
Returns true if the current visitor can see redactions (unpublished versions) of the node.
-
#can_write?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
people who can write: * super user * members of
write_group
if there status is at least ‘user’. -
#draft? ⇒ Boolean
The node has just been created so the creator can still delete it or move it around.
-
#draft_was_true? ⇒ Boolean
The node has just been created so the creator can still delete it or move it around.
-
#empty? ⇒ Boolean
Return true if the node is not a reference for any other nodes.
-
#full_drive?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
‘can_drive?’ without draft? exceptions.
-
#full_drive_was_true?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
‘full_drive?’ before attribute change.
-
#in_circular_reference? ⇒ Boolean
Make sure there is no circular reference (any way to do this faster ?).
-
#public? ⇒ Boolean
Return true if the node can be viewed by all (public).
- #record_must_be_secured ⇒ Object
-
#ref ⇒ Object
Reference to validate access rights.
-
#ref_field_valid? ⇒ Boolean
Verify validity of the reference field.
-
#secure_before_save ⇒ Object
Prepare after save callbacks.
-
#secure_before_validation ⇒ Object
Secure before validation on create (we use the ‘before_validation’ hook instead of ‘before_validation_on_create’ to trigger secure_before_validation before multiversion’s before_validation).
- #secure_before_validation_on_update ⇒ Object
-
#secure_on_create ⇒ Object
1.
- #secure_on_destroy ⇒ Object
-
#secure_on_update ⇒ Object
1.
-
#secure_reference_before_validation ⇒ Object
Make sure the reference object (the one from which this object inherits) exists before validating.
-
#secured? ⇒ Boolean
Return true if the node is properly secured (was loaded with secure).
-
#visitor=(visitor) ⇒ Object
Store visitor to produce scope when needed and to retrieve correct editions.
Instance Method Details
#can_drive?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
Can alter node (move around, name, rwp groups, etc).
-
super user
-
members of
drive_group
if member status is at least ‘user’
103 104 105 |
# File 'lib/zena/acts/secure_node.rb', line 103 def can_drive?(vis=visitor, ugps=visitor.group_ids) !current_site.site_readonly? && ( vis.user? && (ugps.include?(dgroup_id) || draft?) ) end |
#can_drive_was_true?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
‘can_drive?’ before attribute change
108 109 110 |
# File 'lib/zena/acts/secure_node.rb', line 108 def can_drive_was_true?(vis=visitor, ugps=visitor.group_ids) ( vis.user? && (ugps.include?(dgroup_id_was) || draft_was_true?) ) end |
#can_read?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
people who can read:
-
super user
-
members of
read_group
if the node is published and the current date is greater or equal to the publication date -
members of
write_group
66 67 68 69 |
# File 'lib/zena/acts/secure_node.rb', line 66 def can_read?(vis = visitor, ugps=visitor.group_ids) ( ugps.include?(rgroup_id) && publish_from && Time.now >= publish_from ) || ( ugps.include?(wgroup_id) ) end |
#can_see_redactions?(ugps = visitor.group_ids) ⇒ Boolean
Returns true if the current visitor can see redactions (unpublished versions) of the node.
80 81 82 |
# File 'lib/zena/acts/secure_node.rb', line 80 def can_see_redactions?(ugps = visitor.group_ids) ugps.include?(wgroup_id) end |
#can_write?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
people who can write:
-
super user
-
members of
write_group
if there status is at least ‘user’.
74 75 76 |
# File 'lib/zena/acts/secure_node.rb', line 74 def can_write?(vis=visitor, ugps=visitor.group_ids) !current_site.site_readonly? && ( ugps.include?(wgroup_id) && visitor.user?) # write group end |
#draft? ⇒ Boolean
The node has just been created so the creator can still delete it or move it around.
86 87 88 89 90 |
# File 'lib/zena/acts/secure_node.rb', line 86 def draft? !publish_from && visitor.id == user_id && visitor.user? && visitor.id == version.user_id && versions.count == 1 end |
#draft_was_true? ⇒ Boolean
The node has just been created so the creator can still delete it or move it around.
94 95 96 97 98 |
# File 'lib/zena/acts/secure_node.rb', line 94 def draft_was_true? !publish_from_was && visitor.id == user_id_was && visitor.user? && visitor.id == version.user_id_was && versions.count == 1 end |
#empty? ⇒ Boolean
Return true if the node is not a reference for any other nodes
57 58 59 60 |
# File 'lib/zena/acts/secure_node.rb', line 57 def empty? return true if new_record? 0 == self.class.count_by_sql("SELECT COUNT(*) FROM #{self.class.table_name} WHERE #{ref_field} = #{self[:id]}") end |
#full_drive?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
‘can_drive?’ without draft? exceptions
113 114 115 |
# File 'lib/zena/acts/secure_node.rb', line 113 def full_drive?(vis=visitor, ugps=visitor.group_ids) !current_site.site_readonly? && ( vis.user? && ugps.include?(dgroup_id) ) end |
#full_drive_was_true?(vis = visitor, ugps = visitor.group_ids) ⇒ Boolean
‘full_drive?’ before attribute change
118 119 120 |
# File 'lib/zena/acts/secure_node.rb', line 118 def full_drive_was_true?(vis=visitor, ugps=visitor.group_ids) ( vis.user? && ugps.include?(dgroup_id_was) ) end |
#in_circular_reference? ⇒ Boolean
Make sure there is no circular reference (any way to do this faster ?)
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/zena/acts/secure_node.rb', line 296 def in_circular_reference? loop_ids = [self[:id]] curr_ref = ref_field_id in_loop = false while curr_ref != 0 if loop_ids.include?(curr_ref) # detect loops in_loop = true break end loop_ids << curr_ref curr_ref = Zena::Db.fetch_attribute("SELECT #{ref_field} FROM #{self.class.table_name} WHERE id=#{curr_ref}").to_i end errors.add(ref_field, 'circular reference') if in_loop in_loop end |
#public? ⇒ Boolean
Return true if the node can be viewed by all (public)
46 47 48 49 |
# File 'lib/zena/acts/secure_node.rb', line 46 def public? anon = visitor.site.anon can_read?(anon, anon.group_ids) # visible by anonymous end |
#record_must_be_secured ⇒ Object
35 36 37 |
# File 'lib/zena/acts/secure_node.rb', line 35 def record_must_be_secured errors.add(:base, 'record not secured') unless secured? end |
#ref ⇒ Object
Reference to validate access rights
328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/zena/acts/secure_node.rb', line 328 def ref # new record and self as reference (creating root node) return self if ref_field == :id && new_record? if !@ref || (@ref.id != ref_field_id) # no ref or ref changed @ref = secure(ref_class) { ref_class.find_by_id(ref_field_id) } end if @ref && (self.new_record? || (:id == ref_field) || (self[:id] != @ref[:id] )) # reference is accepted only if it is not the same as self or self is root (ref_field==:id set by Node) @ref.freeze else nil end end |
#ref_field_valid? ⇒ Boolean
Verify validity of the reference field.
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/zena/acts/secure_node.rb', line 268 def ref_field_valid? return true unless ref_field_id_changed? # reference changed if published_in_heirs_was_true? # node or some children node was published, moves must be made with drive rights in both # source and destination if ref_field_id == self.id || secure_drive(ref_class) { ref_class.count(:conditions => ['id IN (?)', [ref_field_id, ref_field_id_was]]) != 2 } errors.add(ref_field, "invalid reference") return false end else # node was not visible to others, we need write access to both source and destination if ref_field_id == self.id || secure_write(ref_class) { ref_class.count(:conditions => ['id IN (?)', [ref_field_id, ref_field_id_was]]) != 2 } errors.add(ref_field, "invalid reference") return false end end in_circular_reference? ? false : true end |
#secure_before_save ⇒ Object
Prepare after save callbacks
262 263 264 265 |
# File 'lib/zena/acts/secure_node.rb', line 262 def secure_before_save @needs_inheritance_spread = !new_record? && (rgroup_id_changed? || wgroup_id_changed? || dgroup_id_changed? || skin_id_changed?) true end |
#secure_before_validation ⇒ Object
Secure before validation on create (we use the ‘before_validation’ hook instead of ‘before_validation_on_create’ to trigger secure_before_validation before multiversion’s before_validation).
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/zena/acts/secure_node.rb', line 124 def secure_before_validation return true unless new_record? # Secure before validation on create. # set defaults before validation self[:site_id] = visitor.site.id self[:user_id] = visitor.id self[:ref_lang] = visitor.lang [:rgroup_id, :wgroup_id, :dgroup_id, :skin_id].each do |sym| # not defined => inherit self[sym] ||= ref[sym] end if inherit.nil? if rgroup_id == ref.rgroup_id && wgroup_id == ref.wgroup_id && dgroup_id == ref.dgroup_id self[:inherit] = 1 else self[:inherit] = 0 end end true end |
#secure_before_validation_on_update ⇒ Object
148 149 150 |
# File 'lib/zena/acts/secure_node.rb', line 148 def secure_before_validation_on_update true end |
#secure_on_create ⇒ Object
-
validate the presence of a valid project (one in which the visitor has write access and project<>self !)
-
validate the presence of a valid reference (project or parent) (in which the visitor has write access and ref<>self !)
-
validate
drive_group
value (same as parent or ref.can_drive? and valid) -
validate rw groups :
a. if can_drive? : valid groups b. else inherit or private
-
validate the rest
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/zena/acts/secure_node.rb', line 168 def secure_on_create case inherit when 1 # force inheritance self[:rgroup_id] = ref.rgroup_id self[:wgroup_id] = ref.wgroup_id self[:dgroup_id] = ref.dgroup_id self[:skin_id ] = ref.skin_id when 0 # custom access rights if ref.full_drive? errors.add('rgroup_id', "unknown group") unless visitor.group_ids.include?(rgroup_id) errors.add('wgroup_id', "unknown group") unless visitor.group_ids.include?(wgroup_id) errors.add('dgroup_id', "unknown group") unless visitor.group_ids.include?(dgroup_id) else errors.add('inherit', "custom access rights not allowed") errors.add('rgroup_id', "you cannot change this") unless rgroup_id == ref.rgroup_id errors.add('wgroup_id', "you cannot change this") unless wgroup_id == ref.wgroup_id errors.add('dgroup_id', "you cannot change this") unless dgroup_id == ref.dgroup_id errors.add('skin_id' , "you cannot change this") unless skin_id == ref.skin_id end else errors.add(:inherit, "bad inheritance mode") end end |
#secure_on_destroy ⇒ Object
313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/zena/acts/secure_node.rb', line 313 def secure_on_destroy if new_record? || can_drive_was_true? unless empty? errors.add(:base, 'cannot be removed (contains subpages or data)') false else true end else errors.add(:base, 'You do not have the rights to destroy.') false end end |
#secure_on_update ⇒ Object
-
if dgroup changed from old, make sure user could do this and new group is valid
-
if owner changed from old, make sure only a user in ‘admin’ can do this
-
error if user cannot publish nor manage
-
parent/project changed ? verify ‘publish access to new and old’
-
validate rw groups :
a. can change to 'inherit' if can_drive? or can_drive? and max_status < pub and does not have children b. can change to 'private' if can_drive? c. can change to 'custom' if can_drive?
-
validate the rest
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/zena/acts/secure_node.rb', line 204 def secure_on_update if !changed_without_properties? # Node hasn't been changed (only version edits) return true end if !can_drive_was_true? errors.add(:base, 'You do not have the rights to do this.') unless errors[:base] return false end if user_id_changed? if visitor.is_admin? # only admin can change owners unless secure(User) { User.find_by_id(user_id) } errors.add(:user_id, 'unknown user') end else errors.add(:user_id, 'Only admins can change owners') end end return false unless ref_field_valid? # verify groups if inherit_changed? && !full_drive_was_true? errors.add(:inherit, 'cannot be changed') else case inherit when 1 # inherit rights [:rgroup_id, :wgroup_id, :dgroup_id, :skin_id].each do |sym| if self.send("#{sym}_changed?") && self[sym] != ref[sym] # manual change of value not allowed without changing inherit mode if !full_drive_was_true? errors.add(sym.to_s, 'cannot be changed') else errors.add(sym.to_s, 'cannot be changed without changing inherit mode') end else # in case parent changed, keep in sync self[sym] = ref[sym] end end when 0 # custom rights [:rgroup_id, :wgroup_id, :dgroup_id].each do |sym| if self.send("#{sym}_changed?") && !visitor.group_ids.include?(self[sym]) errors.add(sym.to_s, 'unknown group') end end else errors.add('inherit', 'bad inheritance mode') end end end |
#secure_reference_before_validation ⇒ Object
Make sure the reference object (the one from which this object inherits) exists before validating.
153 154 155 156 157 158 159 |
# File 'lib/zena/acts/secure_node.rb', line 153 def secure_reference_before_validation if ref == nil errors.add(ref_field, "invalid reference") return false end true end |
#secured? ⇒ Boolean
Return true if the node is properly secured (was loaded with secure)
52 53 54 |
# File 'lib/zena/acts/secure_node.rb', line 52 def secured? @visitor && @visitor == Thread.current[:visitor] end |