social_stream-base 0.6.3 → 0.6.5
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.
- data/app/assets/stylesheets/base.css +1 -0
- data/app/assets/stylesheets/contacts.css +2 -1
- data/app/assets/stylesheets/fcbkComplete.css +1 -1
- data/app/assets/stylesheets/header.css +2 -2
- data/app/assets/stylesheets/messages.css +3 -3
- data/app/assets/stylesheets/{spheres.css → relation_customs.css} +0 -0
- data/app/controllers/contacts_controller.rb +9 -4
- data/app/controllers/messages_controller.rb +69 -68
- data/app/controllers/relation/customs_controller.rb +1 -11
- data/app/helpers/activities_helper.rb +1 -2
- data/app/helpers/notifications_helper.rb +3 -2
- data/app/helpers/permissions_helper.rb +5 -5
- data/app/helpers/subjects_helper.rb +9 -0
- data/app/helpers/toolbar_helper.rb +10 -89
- data/app/models/activity.rb +39 -15
- data/app/models/actor.rb +30 -71
- data/app/models/contact.rb +15 -0
- data/app/models/group.rb +1 -3
- data/app/models/permission.rb +9 -72
- data/app/models/profile.rb +7 -2
- data/app/models/relation/custom.rb +6 -33
- data/app/models/relation.rb +15 -39
- data/app/models/user.rb +5 -1
- data/app/views/activities/_new.html.erb +5 -2
- data/app/views/activities/_options.html.erb +2 -2
- data/app/views/activities/_walls.html.erb +1 -1
- data/app/views/contacts/_contact.html.erb +3 -3
- data/app/views/contacts/_form.html.erb +14 -20
- data/app/views/contacts/_index.html.erb +1 -1
- data/app/views/contacts/_suggestions.html.erb +1 -13
- data/app/views/contacts/destroy.js.erb +6 -0
- data/app/views/contacts/edit.html.erb +1 -1
- data/app/views/conversations/_conversation.html.erb +1 -1
- data/app/views/groups/_group.html.erb +1 -1
- data/app/views/groups/_index.html.erb +1 -1
- data/app/views/groups/show.html.erb +1 -1
- data/app/views/invitation_mailer/send_invitation.html.erb +17 -6
- data/app/views/invitation_mailer/send_invitation.text.erb +7 -2
- data/app/views/layouts/_representation.html.erb +10 -6
- data/app/views/layouts/_settings.html.erb +1 -1
- data/app/views/messages/_message.html.erb +1 -1
- data/app/views/messages/new.html.erb +1 -1
- data/app/views/notifications/_notification.html.erb +7 -3
- data/app/views/objects/_new.html.erb +0 -6
- data/app/views/profiles/edit.html.erb +5 -9
- data/app/views/relation/customs/_form.html.erb +2 -2
- data/app/views/{spheres → relation/customs}/_jquery.erb +0 -58
- data/app/views/relation/customs/_list.html.erb +9 -26
- data/app/views/relation/customs/create.js.erb +2 -3
- data/app/views/relation/customs/index.html.erb +67 -0
- data/app/views/users/_index.html.erb +1 -1
- data/app/views/users/show.html.erb +1 -1
- data/config/locales/en.yml +16 -41
- data/config/routes.rb +1 -6
- data/db/migrate/20110705103202_empty_ties_count.rb +4 -0
- data/db/migrate/20110712090343_remove_spheres.rb +30 -0
- data/db/migrate/20110712142140_remove_permission_function.rb +26 -0
- data/lib/generators/social_stream/base/install_generator.rb +4 -0
- data/lib/generators/social_stream/base/templates/mailboxer_custom.rb +13 -0
- data/lib/generators/social_stream/base/templates/navigation.rb +4 -0
- data/lib/generators/social_stream/base/templates/relations.yml +14 -20
- data/lib/social_stream/ability.rb +1 -2
- data/lib/social_stream/base/version.rb +1 -1
- data/lib/social_stream/migration_finder.rb +19 -0
- data/lib/social_stream/toolbar_config.rb +113 -0
- data/lib/social_stream-base.rb +1 -0
- data/lib/tasks/db/populate.rake +1 -1
- data/social_stream-base.gemspec +4 -2
- data/spec/controllers/contacts_controller_spec.rb +1 -1
- data/spec/controllers/permissions_controller_spec.rb +1 -2
- data/spec/controllers/posts_controller_spec.rb +2 -2
- data/spec/controllers/relation_customs_controller_spec.rb +69 -62
- data/spec/dummy/config/database.yml +7 -0
- data/spec/dummy/config/relations.yml +14 -20
- data/spec/factories/relation_custom.rb +1 -1
- data/spec/factories/tie.rb +4 -0
- data/spec/models/activity_spec.rb +11 -2
- data/spec/models/user_spec.rb +68 -9
- data/spec/spec_helper.rb +0 -3
- data/spec/support/db.rb +9 -0
- data/spec/support/migrations.rb +3 -12
- metadata +19 -25
- data/app/controllers/spheres_controller.rb +0 -12
- data/app/models/sphere.rb +0 -9
- data/app/views/relation/customs/_index.html.erb +0 -28
- data/app/views/relation/customs/index.js.erb +0 -2
- data/app/views/spheres/_form.html.erb +0 -28
- data/app/views/spheres/_list.html.erb +0 -19
- data/app/views/spheres/create.js.erb +0 -20
- data/app/views/spheres/index.html.erb +0 -74
- data/spec/controllers/spheres_controller_spec.rb +0 -116
- data/spec/factories/sphere.rb +0 -5
- data/spec/models/relation_custom_spec.rb +0 -14
data/app/models/actor.rb
CHANGED
@@ -56,11 +56,6 @@ class Actor < ActiveRecord::Base
|
|
56
56
|
:uniq => true
|
57
57
|
|
58
58
|
has_many :relations
|
59
|
-
has_many :spheres
|
60
|
-
|
61
|
-
has_many :relation_customs,
|
62
|
-
:through => :spheres,
|
63
|
-
:source => :customs
|
64
59
|
|
65
60
|
scope :alphabetic, order('actors.name')
|
66
61
|
|
@@ -140,12 +135,31 @@ class Actor < ActiveRecord::Base
|
|
140
135
|
end
|
141
136
|
end
|
142
137
|
|
138
|
+
# Returns the email used for Mailboxer
|
139
|
+
def mailboxer_email
|
140
|
+
return email if email.present?
|
141
|
+
if (group = self.subject).is_a? Group
|
142
|
+
relation = group.relation_customs.sort.first
|
143
|
+
receivers = group.contact_actors(:direction => :sent, :relations => relation)
|
144
|
+
emails = Array.new
|
145
|
+
receivers.each do |receiver|
|
146
|
+
emails << receiver.mailboxer_email
|
147
|
+
end
|
148
|
+
return emails
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
143
152
|
# The subject instance for this actor
|
144
153
|
def subject
|
145
154
|
subtype_instance ||
|
146
155
|
activity_object.try(:object)
|
147
156
|
end
|
148
157
|
|
158
|
+
# All the {Relation relations} defined by this {Actor}
|
159
|
+
def relation_customs
|
160
|
+
relations.where(:type => 'Relation::Custom')
|
161
|
+
end
|
162
|
+
|
149
163
|
# A given relation defined and managed by this actor
|
150
164
|
def relation_custom(name)
|
151
165
|
relation_customs.find_by_name(name)
|
@@ -161,7 +175,7 @@ class Actor < ActiveRecord::Base
|
|
161
175
|
# Options:
|
162
176
|
# * type: Filter by the class of the contacts.
|
163
177
|
# * direction: sent or received
|
164
|
-
# * relations: Restrict the relations of considered ties
|
178
|
+
# * relations: Restrict the relations of considered ties. Defaults to {Relation::Custom relations of custom type}
|
165
179
|
# * include_self: False by default, don't include this actor as subject even they have ties with themselves.
|
166
180
|
#
|
167
181
|
def contact_actors(options = {})
|
@@ -169,15 +183,15 @@ class Actor < ActiveRecord::Base
|
|
169
183
|
subject_classes = subject_types.map{ |s| s.to_s.classify }
|
170
184
|
|
171
185
|
as = Actor.select("DISTINCT actors.*").
|
172
|
-
|
173
|
-
|
186
|
+
where('actors.subject_type' => subject_classes).
|
187
|
+
includes(subject_types)
|
174
188
|
|
175
189
|
|
176
190
|
case options[:direction]
|
177
191
|
when :sent
|
178
|
-
as = as.
|
192
|
+
as = as.joins(:received_ties => :relation).merge(Contact.sent_by(self))
|
179
193
|
when :received
|
180
|
-
as = as.
|
194
|
+
as = as.joins(:sent_ties => :relation).merge(Contact.received_by(self))
|
181
195
|
else
|
182
196
|
raise "contact actors in both directions are not supported yet"
|
183
197
|
end
|
@@ -187,7 +201,9 @@ class Actor < ActiveRecord::Base
|
|
187
201
|
end
|
188
202
|
|
189
203
|
if options[:relations].present?
|
190
|
-
as = as.
|
204
|
+
as = as.merge(Tie.related_by(options[:relations]))
|
205
|
+
else
|
206
|
+
as = as.merge(Relation.where(:type => 'Relation::Custom'))
|
191
207
|
end
|
192
208
|
|
193
209
|
as
|
@@ -241,7 +257,7 @@ class Actor < ActiveRecord::Base
|
|
241
257
|
# Candidates are all the instance of "type" minus all the subjects
|
242
258
|
# that are receiving any tie from this actor
|
243
259
|
candidates = candidates_classes.inject([]) do |cs, klass|
|
244
|
-
cs += klass.all - contact_subjects(:type => klass.to_s.underscore, :direction => :sent)
|
260
|
+
cs += klass.all - contact_subjects(:type => klass.to_s.underscore, :direction => :sent, :relations => relations.to_a)
|
245
261
|
cs -= Array(subject) if subject.is_a?(klass)
|
246
262
|
cs
|
247
263
|
end
|
@@ -250,7 +266,7 @@ class Actor < ActiveRecord::Base
|
|
250
266
|
|
251
267
|
return nil unless candidate.present?
|
252
268
|
|
253
|
-
|
269
|
+
contact_to!(candidate)
|
254
270
|
end
|
255
271
|
|
256
272
|
# Set of ties sent by this actor received by subject
|
@@ -279,30 +295,15 @@ class Actor < ActiveRecord::Base
|
|
279
295
|
any?
|
280
296
|
end
|
281
297
|
|
282
|
-
# The relations that allow attaching an activity to them. This method is used for caching
|
283
|
-
def active_relations
|
284
|
-
@active_relations ||= { :sender => {}, :receiver => {} }
|
285
|
-
end
|
286
|
-
|
287
298
|
# An {Activity} can be shared with multiple {audicences Audience}, which corresponds to a {Relation}.
|
288
299
|
#
|
289
300
|
# This method returns all the {relations Relation} that this actor can use to broadcast an Activity
|
290
301
|
#
|
291
|
-
# Options:
|
292
|
-
# from:: limit the relations to one side, from the :sender or the :receiver of the activity
|
293
302
|
#
|
294
303
|
def activity_relations(subject, options = {})
|
295
304
|
return relations if Actor.normalize(subject) == self
|
296
305
|
|
297
|
-
|
298
|
-
when :sender
|
299
|
-
sender_activity_relations(subject)
|
300
|
-
when :receiver
|
301
|
-
receiver_activity_relations(subject)
|
302
|
-
else
|
303
|
-
sender_activity_relations(subject) +
|
304
|
-
receiver_activity_relations(subject)
|
305
|
-
end
|
306
|
+
Array.new
|
306
307
|
end
|
307
308
|
|
308
309
|
# Are there any activity_relations present?
|
@@ -310,48 +311,6 @@ class Actor < ActiveRecord::Base
|
|
310
311
|
activity_relations(*args).any?
|
311
312
|
end
|
312
313
|
|
313
|
-
# Relations from this actor that can be read by subject
|
314
|
-
def sender_activity_relations(subject)
|
315
|
-
active_relations[:sender][subject] ||=
|
316
|
-
Relation.allow(subject, 'read', 'activity', :owner => self)
|
317
|
-
end
|
318
|
-
|
319
|
-
def receiver_activity_relations(subject)
|
320
|
-
active_relations[:receiver][subject] ||=
|
321
|
-
Relation.allow(self, 'create', 'activity', :owner => subject)
|
322
|
-
end
|
323
|
-
|
324
|
-
# Builds a hash of options their spheres as keys
|
325
|
-
def grouped_activity_relations(subject)
|
326
|
-
rels = activity_relations(subject)
|
327
|
-
|
328
|
-
spheres =
|
329
|
-
rels.map{ |r| r.respond_to?(:sphere) ? r.sphere : I18n.t('relation_public.name') }.uniq
|
330
|
-
|
331
|
-
spheres.sort!{ |x, y|
|
332
|
-
case x
|
333
|
-
when Sphere
|
334
|
-
case y
|
335
|
-
when Sphere
|
336
|
-
x.id <=> y.id
|
337
|
-
else
|
338
|
-
-1
|
339
|
-
end
|
340
|
-
else
|
341
|
-
1
|
342
|
-
end
|
343
|
-
}
|
344
|
-
|
345
|
-
spheres.map{ |s|
|
346
|
-
case s
|
347
|
-
when Sphere
|
348
|
-
[ s.name, rels.select{ |r| r.respond_to?(:sphere) && r.sphere == s }.sort.map{ |u| [ u.name, u.id ] } ]
|
349
|
-
else
|
350
|
-
[ s, rels.select{ |r| r.is_a?(Relation::Public) }.map{ |u| [ u.name, u.id ] } ]
|
351
|
-
end
|
352
|
-
}
|
353
|
-
end
|
354
|
-
|
355
314
|
# Is this {Actor} allowed to create a comment on activity?
|
356
315
|
#
|
357
316
|
# We are allowing comments from everyone signed in by now
|
data/app/models/contact.rb
CHANGED
@@ -100,6 +100,21 @@ class Contact < ActiveRecord::Base
|
|
100
100
|
association(:relations).ids_writer(ids)
|
101
101
|
end
|
102
102
|
|
103
|
+
# Is this {Contact} +new+ or +edit+ for {SocialStream::Models::Subject subject} ?
|
104
|
+
#
|
105
|
+
# action is +new+ when, despite of being created, it has not {Tie ties} or it has a {Tie} with a
|
106
|
+
# {Relation::Public public relation}.
|
107
|
+
#
|
108
|
+
# The contact's action is +edit+ when it has any {Tie} with a {Relation::Custom custom relation}
|
109
|
+
#
|
110
|
+
def action
|
111
|
+
if ties_count > 0 && relations.where(:type => 'Relation::Custom').any?
|
112
|
+
'edit'
|
113
|
+
else
|
114
|
+
'new'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
103
118
|
private
|
104
119
|
|
105
120
|
def remove_follower(ids)
|
data/app/models/group.rb
CHANGED
data/app/models/permission.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# SocialStream provides a
|
2
|
-
# of the social network.
|
1
|
+
# SocialStream provides a system of permissions based on the {Relation relations}
|
2
|
+
# of the social network as roles.
|
3
3
|
#
|
4
4
|
# = Permissions and Relations
|
5
5
|
#
|
@@ -13,9 +13,9 @@
|
|
13
13
|
#
|
14
14
|
# = Permissions description
|
15
15
|
#
|
16
|
-
# Permissions are composed by *action
|
16
|
+
# Permissions are composed by *action* and *object*. Action and object
|
17
17
|
# are typical in content management systems, e.g. <tt>create activity</tt>,
|
18
|
-
# <tt>update tie</tt>, <tt>read post</tt>.
|
18
|
+
# <tt>update tie</tt>, <tt>read post</tt>.
|
19
19
|
#
|
20
20
|
# == Actions
|
21
21
|
#
|
@@ -32,33 +32,8 @@
|
|
32
32
|
#
|
33
33
|
# +activity+:: all the objects in a wall: posts, comments
|
34
34
|
#
|
35
|
-
# Other
|
35
|
+
# Other objects currently not implemented could be +tie+, +post+, +comment+ or +message+
|
36
36
|
#
|
37
|
-
# == Functions
|
38
|
-
#
|
39
|
-
# Function is a novel feature. It supports applying the permission to other related relations and ties.
|
40
|
-
# It is required because the set of ties changes while {SocialStream::Models::Subject subjects } build their network.
|
41
|
-
# Besides {SocialStream::Models::Subject subjects} can describe and
|
42
|
-
# customize their own relations and permissions.
|
43
|
-
#
|
44
|
-
# Available functions are:
|
45
|
-
#
|
46
|
-
# +same_level+:: the permission applies to all the objects in same relation
|
47
|
-
#
|
48
|
-
# Example: the _friend_ relation has the permission
|
49
|
-
# <tt>read tie same_level</tt>. If _Alice_ has a _friend_ tie with
|
50
|
-
# _Bob_, she is granting him access to read all the contacts of type _friend_
|
51
|
-
##
|
52
|
-
# +same_and_lower_levels+:: apply the permission to all the related objects attached to a relation weaker
|
53
|
-
# or equal than this.#
|
54
|
-
#
|
55
|
-
# Example: if the _member_ relation of a group has the permission
|
56
|
-
# <tt>create activity same_and_lower_levels</tt>, its members
|
57
|
-
# can also create activities attached to the weaker relations of
|
58
|
-
# _acquaintance_ and _public_.
|
59
|
-
# This means than a group _member_ can create activities at different
|
60
|
-
# levels of the sphere, and therefore, with different levels of
|
61
|
-
# access.
|
62
37
|
#
|
63
38
|
class Permission < ActiveRecord::Base
|
64
39
|
has_many :relation_permissions, :dependent => :destroy
|
@@ -68,51 +43,13 @@ class Permission < ActiveRecord::Base
|
|
68
43
|
scope p, where(:action => p) # scope :represent, where(:action => 'represent')
|
69
44
|
end
|
70
45
|
|
71
|
-
RelationConditions = {
|
72
|
-
'same_level' =>
|
73
|
-
"relations.id = relations_as.id",
|
74
|
-
'same_and_lower_levels' =>
|
75
|
-
"(relations.id = relations_as.id OR relations.ancestry = relations_as.id || '' OR relations.ancestry = (relations_as.ancestry || '/' || relations_as.id) OR relations.ancestry LIKE (relations_as.id || '/%') OR relations.ancestry LIKE (relations_as.ancestry || '/' || relations_as.id || '/%')) OR (relations.actor_id = relations_as.actor_id AND relations.type = 'Relation::Public')"
|
76
|
-
}
|
77
|
-
|
78
|
-
class << self
|
79
|
-
# Builds SQL conditions based on {RelationConditions}
|
80
|
-
def relation_conditions
|
81
|
-
RelationConditions.inject([]){ |result, pc|
|
82
|
-
result <<
|
83
|
-
"(#{ pc.last }) AND #{ sanitize_sql('permissions_as.function' => pc.first) }"
|
84
|
-
}.join(" OR ")
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
46
|
# An explanation of the permissions. Type can be brief or detailed.
|
89
|
-
# If detailed, description includes
|
47
|
+
# If detailed, description includes more information about the relation
|
90
48
|
def description(type, relation = nil)
|
91
|
-
options =
|
49
|
+
options = {}
|
50
|
+
options[:relation] = relation.name if relation.present?
|
92
51
|
|
93
|
-
I18n.t "permission.description.#{ type }.#{ action }.#{ object || "nil" }
|
52
|
+
I18n.t "permission.description.#{ type }.#{ action }.#{ object || "nil" }",
|
94
53
|
options
|
95
54
|
end
|
96
|
-
|
97
|
-
private
|
98
|
-
|
99
|
-
def description_options(relation)
|
100
|
-
{
|
101
|
-
:sphere => relation.sphere.name,
|
102
|
-
:public => I18n.t('relation_public.name')
|
103
|
-
}.tap do |h|
|
104
|
-
case function
|
105
|
-
when NilClass, "same_level"
|
106
|
-
h[:relation] = relation.name
|
107
|
-
when "same_and_lower_levels"
|
108
|
-
h[:relations] = relation.
|
109
|
-
weaker_or_equal.
|
110
|
-
sort.
|
111
|
-
map(&:name).
|
112
|
-
join(", ")
|
113
|
-
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
118
55
|
end
|
data/app/models/profile.rb
CHANGED
@@ -17,18 +17,23 @@ class Profile < ActiveRecord::Base
|
|
17
17
|
|
18
18
|
validate :validate_birthday
|
19
19
|
|
20
|
-
def birthday=(value)
|
20
|
+
def birthday=(value)
|
21
|
+
|
22
|
+
puts "He entrado en el metodo birthday con un :" + value.class.to_s
|
23
|
+
|
21
24
|
if value.blank?
|
22
25
|
@birthday_formatted_invalid = false
|
23
26
|
super value
|
24
27
|
else
|
25
28
|
begin
|
26
|
-
super Date.parse(value)
|
29
|
+
#super Date.parse(value)
|
30
|
+
super value
|
27
31
|
@birthday_formatted_invalid = false
|
28
32
|
rescue
|
29
33
|
@birthday_formatted_invalid = true
|
30
34
|
end
|
31
35
|
end
|
36
|
+
|
32
37
|
end
|
33
38
|
|
34
39
|
def age
|
@@ -13,16 +13,10 @@ class Relation::Custom < Relation
|
|
13
13
|
inspect
|
14
14
|
has_ancestry
|
15
15
|
|
16
|
-
attr_protected :actor_id
|
17
|
-
|
18
|
-
belongs_to :sphere
|
19
16
|
belongs_to :actor
|
20
17
|
|
21
|
-
validates_presence_of :name, :
|
22
|
-
validates_uniqueness_of :name, :scope => :
|
23
|
-
|
24
|
-
before_validation :assign_parent, :on => :create
|
25
|
-
before_validation :assign_actor, :on => :create
|
18
|
+
validates_presence_of :name, :actor_id
|
19
|
+
validates_uniqueness_of :name, :scope => :actor_id
|
26
20
|
|
27
21
|
class << self
|
28
22
|
# Relations configuration
|
@@ -40,18 +34,15 @@ class Relation::Custom < Relation
|
|
40
34
|
rels = {}
|
41
35
|
|
42
36
|
cfg_rels.each_pair do |name, cfg_rel|
|
43
|
-
raise("Must associatiate relation #{ cfg_rel['name'] } to a sphere") if cfg_rel['sphere'].blank?
|
44
|
-
sphere = actor.spheres.find_or_create_by_name(cfg_rel['sphere'])
|
45
|
-
|
46
37
|
rels[name] =
|
47
|
-
create! :
|
48
|
-
:
|
49
|
-
:
|
38
|
+
create! :actor => actor,
|
39
|
+
:name => cfg_rel['name'],
|
40
|
+
:receiver_type => cfg_rel['receiver_type']
|
50
41
|
|
51
42
|
if (ps = cfg_rel['permissions']).present?
|
52
43
|
ps.each do |p|
|
53
44
|
rels[name].permissions <<
|
54
|
-
Permission.
|
45
|
+
Permission.find_or_create_by_action_and_object(*p)
|
55
46
|
end
|
56
47
|
end
|
57
48
|
end
|
@@ -103,22 +94,4 @@ class Relation::Custom < Relation
|
|
103
94
|
def stronger_or_equal
|
104
95
|
path
|
105
96
|
end
|
106
|
-
|
107
|
-
private
|
108
|
-
|
109
|
-
# Before create callback
|
110
|
-
#
|
111
|
-
# Assign the last relation as parent if there are other custom relations in the sphere
|
112
|
-
def assign_parent
|
113
|
-
return if parent.present? || sphere.customs.blank?
|
114
|
-
|
115
|
-
self.parent = sphere.customs.sort.last
|
116
|
-
end
|
117
|
-
|
118
|
-
# Before create callback
|
119
|
-
#
|
120
|
-
# Assign the sphere's actor
|
121
|
-
def assign_actor
|
122
|
-
self.actor = sphere.actor
|
123
|
-
end
|
124
97
|
end
|
data/app/models/relation.rb
CHANGED
@@ -30,6 +30,7 @@ class Relation < ActiveRecord::Base
|
|
30
30
|
has_many :permissions, :through => :relation_permissions
|
31
31
|
|
32
32
|
has_many :ties, :dependent => :destroy
|
33
|
+
has_many :contacts, :through => :ties
|
33
34
|
|
34
35
|
scope :mode, lambda { |st, rt|
|
35
36
|
where(:sender_type => st, :receiver_type => rt)
|
@@ -57,7 +58,7 @@ class Relation < ActiveRecord::Base
|
|
57
58
|
when Array
|
58
59
|
r.map{ |e| Relation.normalize(e, options) }
|
59
60
|
else
|
60
|
-
raise "Unable to normalize relation #{ r.inspect }"
|
61
|
+
raise "Unable to normalize relation #{ r.class }: #{ r.inspect }"
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
@@ -76,59 +77,34 @@ class Relation < ActiveRecord::Base
|
|
76
77
|
#
|
77
78
|
# Options:
|
78
79
|
# in:: Limit possible relations to a set
|
79
|
-
# owner:: The owner of the relations
|
80
80
|
# public_relations:: include also {Relation::Public} whose activities can always be read
|
81
81
|
def allow(subject, action, object, options = {})
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
82
|
+
q =
|
83
|
+
select("DISTINCT relations.*").
|
84
|
+
joins(:contacts).
|
85
|
+
joins(:permissions)
|
86
86
|
|
87
|
-
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
rels
|
92
|
-
end
|
93
|
-
|
94
|
-
# Relation conditions
|
95
|
-
# Some relations can have permissions that grant permissions to other relations
|
96
|
-
# through Relation#function
|
97
|
-
conds = Permission.relation_conditions
|
98
|
-
|
99
|
-
# Permission conditions
|
100
|
-
# Set the permission conditions
|
101
|
-
conds = "( #{ conds } ) AND #{ sanitize_sql('permissions_as.action' => action) } AND #{ sanitize_sql('permissions_as.object' => object) }"
|
87
|
+
conds =
|
88
|
+
Permission.arel_table[:action].eq(action).and(Permission.arel_table[:object].eq(object))
|
102
89
|
|
103
90
|
# Relation::Public permissions cannot be customized yet
|
104
91
|
if action == 'read' && object == 'activity' && (options[:public].nil? || options[:public])
|
105
|
-
conds =
|
106
|
-
"( #{ conds } ) OR #{ sanitize_sql('relations.type' => 'Relation::Public') }"
|
107
|
-
end
|
108
|
-
|
109
|
-
# subject conditions
|
110
|
-
#
|
111
|
-
# Relation permissions are granted to the contact receiver.
|
112
|
-
# However, relation owners have all the permissions
|
113
|
-
conds = "( ( #{ conds } ) AND #{ sanitize_sql('contacts_as.receiver_id' => Actor.normalize_id(subject)) } ) OR #{ sanitize_sql('relations.actor_id' => Actor.normalize_id(subject)) }"
|
114
|
-
|
115
|
-
# Add owner condition
|
116
|
-
if options[:owner].present?
|
117
|
-
conds = "( #{ conds } ) AND #{ sanitize_sql('relations.actor_id' => Actor.normalize_id(options[:owner])) }"
|
92
|
+
conds = conds.or(Relation.arel_table[:type].eq('Relation::Public'))
|
118
93
|
end
|
119
94
|
|
120
95
|
# Add in condition
|
121
96
|
if options[:in].present?
|
122
|
-
conds =
|
97
|
+
conds = conds.and(Relation.arel_table[:id].in(Relation.normalize_id(Array(options[:in]))))
|
123
98
|
end
|
124
99
|
|
125
|
-
|
126
|
-
|
127
|
-
|
100
|
+
# subject conditions
|
101
|
+
conds = conds.and(Contact.arel_table[:receiver_id].eq(Actor.normalize_id(subject)))
|
102
|
+
|
103
|
+
q.where(conds)
|
128
104
|
end
|
129
105
|
|
130
106
|
def allow?(*args)
|
131
|
-
allow(*args).any?
|
107
|
+
allow(*args).to_a.any?
|
132
108
|
end
|
133
109
|
end
|
134
110
|
|