social_stream 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/Gemfile.lock +48 -44
  2. data/app/controllers/ties_controller.rb +1 -0
  3. data/app/models/ability.rb +2 -0
  4. data/app/models/actor.rb +7 -8
  5. data/app/models/permission.rb +80 -0
  6. data/app/models/relation.rb +1 -6
  7. data/app/models/tie.rb +34 -42
  8. data/app/views/activities/_child.html.erb +1 -2
  9. data/app/views/activities/_jquery.html.erb +2 -3
  10. data/app/views/activities/_options.html.erb +1 -1
  11. data/app/views/activities/_root.html.erb +1 -2
  12. data/app/views/comments/_new.html.erb +18 -15
  13. data/app/views/groups/_followers.html.erb +16 -14
  14. data/app/views/groups/_group.html.erb +1 -1
  15. data/app/views/groups/_location.html.erb +3 -0
  16. data/app/views/groups/show.html.erb +2 -2
  17. data/app/views/home/_contacts.html.erb +2 -2
  18. data/app/views/home/_groups.html.erb +23 -0
  19. data/app/views/home/_options.html.erb +0 -6
  20. data/app/views/home/_right.html.erb +1 -6
  21. data/app/views/home/index.html.erb +3 -3
  22. data/app/views/posts/_post.html.erb +1 -1
  23. data/app/views/ties/_suggestions.html.erb +7 -1
  24. data/app/views/ties/_tie.html.erb +1 -1
  25. data/app/views/users/_contacts.html.erb +16 -18
  26. data/app/views/users/_groups.html.erb +1 -2
  27. data/app/views/users/_location.html.erb +3 -0
  28. data/app/views/users/_logo.html.erb +2 -4
  29. data/app/views/users/_menu.html.erb +3 -26
  30. data/app/views/users/_middle_show.html.erb +0 -1
  31. data/app/views/users/_options.html.erb +5 -0
  32. data/app/views/users/_right_show.html.erb +9 -0
  33. data/app/views/users/show.html.erb +2 -2
  34. data/config/locales/en.yml +3 -2
  35. data/lib/generators/social_stream/templates/public/images/btn/{btn_follower.png → btn_group.png} +0 -0
  36. data/lib/generators/social_stream/templates/public/images/logos/actor/group.png +0 -0
  37. data/lib/generators/social_stream/templates/public/images/logos/actor/user.png +0 -0
  38. data/lib/generators/social_stream/templates/public/images/logos/original/group.png +0 -0
  39. data/lib/generators/social_stream/templates/public/images/logos/original/user.png +0 -0
  40. data/lib/generators/social_stream/templates/public/images/logos/profile/group.png +0 -0
  41. data/lib/generators/social_stream/templates/public/images/logos/profile/user.png +0 -0
  42. data/lib/generators/social_stream/templates/public/images/logos/tie/group.png +0 -0
  43. data/lib/generators/social_stream/templates/public/images/logos/tie/user.png +0 -0
  44. data/lib/generators/social_stream/templates/public/images/{btn/title_background.png → title_background.png} +0 -0
  45. data/lib/generators/social_stream/templates/public/stylesheets/middle.css +1 -1
  46. data/lib/generators/social_stream/templates/public/stylesheets/right.css +1 -0
  47. data/lib/generators/social_stream/templates/seeds.yml +20 -20
  48. data/lib/social_stream/ability.rb +26 -0
  49. data/lib/social_stream/version.rb +1 -1
  50. data/lib/tasks/db/populate.rake +25 -6
  51. data/social_stream.gemspec +2 -1
  52. data/spec/dummy/db/seeds/social_stream.yml +43 -33
  53. data/spec/factories/tie.rb +15 -10
  54. data/spec/models/activity_spec.rb +83 -146
  55. data/spec/models/tie_spec.rb +113 -0
  56. metadata +52 -25
  57. data/spec/dummy/app/models/ability.rb +0 -23
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- social_stream (0.1.6)
5
- atd-ancestry
4
+ social_stream (0.1.7)
5
+ atd-ancestry (= 1.3.0)
6
6
  cancan (~> 1.4.0)
7
7
  devise (~> 1.1.3)
8
8
  foreigner (~> 0.9.1)
@@ -11,43 +11,43 @@ PATH
11
11
  nested_set (~> 1.5.3)
12
12
  paperclip (~> 2.3.4)
13
13
  stringex (~> 1.2.0)
14
+ will_paginate (~> 2.3.15)
14
15
 
15
16
  GEM
16
17
  remote: http://rubygems.org/
17
18
  specs:
18
19
  abstract (1.0.0)
19
- actionmailer (3.0.1)
20
- actionpack (= 3.0.1)
21
- mail (~> 2.2.5)
22
- actionpack (3.0.1)
23
- activemodel (= 3.0.1)
24
- activesupport (= 3.0.1)
20
+ actionmailer (3.0.3)
21
+ actionpack (= 3.0.3)
22
+ mail (~> 2.2.9)
23
+ actionpack (3.0.3)
24
+ activemodel (= 3.0.3)
25
+ activesupport (= 3.0.3)
25
26
  builder (~> 2.1.2)
26
27
  erubis (~> 2.6.6)
27
- i18n (~> 0.4.1)
28
+ i18n (~> 0.4)
28
29
  rack (~> 1.2.1)
29
- rack-mount (~> 0.6.12)
30
- rack-test (~> 0.5.4)
30
+ rack-mount (~> 0.6.13)
31
+ rack-test (~> 0.5.6)
31
32
  tzinfo (~> 0.3.23)
32
- activemodel (3.0.1)
33
- activesupport (= 3.0.1)
33
+ activemodel (3.0.3)
34
+ activesupport (= 3.0.3)
34
35
  builder (~> 2.1.2)
35
- i18n (~> 0.4.1)
36
- activerecord (3.0.1)
37
- activemodel (= 3.0.1)
38
- activesupport (= 3.0.1)
39
- arel (~> 1.0.0)
36
+ i18n (~> 0.4)
37
+ activerecord (3.0.3)
38
+ activemodel (= 3.0.3)
39
+ activesupport (= 3.0.3)
40
+ arel (~> 2.0.2)
40
41
  tzinfo (~> 0.3.23)
41
- activeresource (3.0.1)
42
- activemodel (= 3.0.1)
43
- activesupport (= 3.0.1)
44
- activesupport (3.0.1)
45
- arel (1.0.1)
46
- activesupport (~> 3.0.0)
42
+ activeresource (3.0.3)
43
+ activemodel (= 3.0.3)
44
+ activesupport (= 3.0.3)
45
+ activesupport (3.0.3)
46
+ arel (2.0.3)
47
47
  atd-ancestry (1.3.0)
48
48
  bcrypt-ruby (2.1.2)
49
49
  builder (2.1.2)
50
- cancan (1.4.0)
50
+ cancan (1.4.1)
51
51
  capybara (0.3.9)
52
52
  culerity (>= 0.2.4)
53
53
  mime-types (>= 1.16)
@@ -69,6 +69,7 @@ GEM
69
69
  ffi (0.6.3)
70
70
  rake (>= 0.8.7)
71
71
  foreigner (0.9.1)
72
+ forgery (0.3.6)
72
73
  has_scope (0.5.0)
73
74
  i18n (0.4.2)
74
75
  inherited_resources (1.1.2)
@@ -79,16 +80,16 @@ GEM
79
80
  thor (~> 0.14.4)
80
81
  json_pure (1.4.6)
81
82
  linecache (0.43)
82
- mail (2.2.9)
83
+ mail (2.2.10)
83
84
  activesupport (>= 2.3.6)
84
85
  i18n (~> 0.4.1)
85
86
  mime-types (~> 1.16)
86
87
  treetop (~> 1.4.8)
87
88
  mime-types (1.16)
88
- nested_set (1.5.3)
89
+ nested_set (1.5.4)
89
90
  activerecord (>= 3.0.0)
90
91
  railties (>= 3.0.0)
91
- nokogiri (1.4.3.1)
92
+ nokogiri (1.4.4)
92
93
  paperclip (2.3.5)
93
94
  activerecord
94
95
  activesupport
@@ -98,19 +99,19 @@ GEM
98
99
  rack (>= 1.0.0)
99
100
  rack-test (0.5.6)
100
101
  rack (>= 1.0)
101
- rails (3.0.1)
102
- actionmailer (= 3.0.1)
103
- actionpack (= 3.0.1)
104
- activerecord (= 3.0.1)
105
- activeresource (= 3.0.1)
106
- activesupport (= 3.0.1)
107
- bundler (~> 1.0.0)
108
- railties (= 3.0.1)
109
- railties (3.0.1)
110
- actionpack (= 3.0.1)
111
- activesupport (= 3.0.1)
112
- rake (>= 0.8.4)
113
- thor (~> 0.14.0)
102
+ rails (3.0.3)
103
+ actionmailer (= 3.0.3)
104
+ actionpack (= 3.0.3)
105
+ activerecord (= 3.0.3)
106
+ activeresource (= 3.0.3)
107
+ activesupport (= 3.0.3)
108
+ bundler (~> 1.0)
109
+ railties (= 3.0.3)
110
+ railties (3.0.3)
111
+ actionpack (= 3.0.3)
112
+ activesupport (= 3.0.3)
113
+ rake (>= 0.8.7)
114
+ thor (~> 0.14.4)
114
115
  rake (0.8.7)
115
116
  responders (0.6.2)
116
117
  rspec (2.0.1)
@@ -139,29 +140,32 @@ GEM
139
140
  sqlite3-ruby (1.3.2)
140
141
  stringex (1.2.0)
141
142
  thor (0.14.4)
142
- treetop (1.4.8)
143
+ treetop (1.4.9)
143
144
  polyglot (>= 0.3.1)
144
145
  tzinfo (0.3.23)
145
146
  warden (0.10.7)
146
147
  rack (>= 1.0.0)
148
+ will_paginate (2.3.15)
147
149
 
148
150
  PLATFORMS
149
151
  ruby
150
152
 
151
153
  DEPENDENCIES
152
- atd-ancestry
154
+ atd-ancestry (= 1.3.0)
153
155
  cancan (~> 1.4.0)
154
156
  capybara (~> 0.3.9)
155
157
  devise (~> 1.1.3)
156
158
  factory_girl (~> 1.3.2)
157
159
  foreigner (~> 0.9.1)
160
+ forgery (~> 0.3.6)
158
161
  inherited_resources (~> 1.1.2)
159
162
  jquery-rails (~> 0.2.5)
160
163
  nested_set (~> 1.5.3)
161
164
  paperclip (~> 2.3.4)
162
- rails (~> 3.0.1)
165
+ rails (~> 3.0.3)
163
166
  rspec-rails (~> 2.0.0)
164
167
  ruby-debug (~> 0.10.3)
165
168
  social_stream!
166
169
  sqlite3-ruby
167
170
  stringex (~> 1.2.0)
171
+ will_paginate (~> 2.3.15)
@@ -5,5 +5,6 @@ class TiesController < InheritedResources::Base
5
5
 
6
6
  def suggestion
7
7
  @tie = current_user.suggestion
8
+ render :layout => false
8
9
  end
9
10
  end
@@ -0,0 +1,2 @@
1
+ class Ability < SocialStream::Ability
2
+ end
data/app/models/actor.rb CHANGED
@@ -9,7 +9,7 @@ class Actor < ActiveRecord::Base
9
9
  has_attached_file :logo,
10
10
  :styles => { :tie => "30x30>",
11
11
  :actor => '35x35>',
12
- :profile => '94x65' },
12
+ :profile => '94x94' },
13
13
  :default_url => "/images/:attachment/:style/:subtype_class.png"
14
14
 
15
15
  has_many :sent_ties,
@@ -142,7 +142,7 @@ class Actor < ActiveRecord::Base
142
142
 
143
143
  # All the ties this actor has with subject that support activities
144
144
  def active_ties_to(subject)
145
- sent_ties.received_by(subject).active
145
+ sent_ties.received_by(subject).allowed(self, 'create', 'activity')
146
146
  end
147
147
 
148
148
  def pending_ties
@@ -159,16 +159,15 @@ class Actor < ActiveRecord::Base
159
159
  # The set of activities in the wall of this actor, includes all the activities
160
160
  # from the ties the actor has access to
161
161
  #
162
- # TODO: ties, authorization
163
162
  def wall
164
- Activity.wall ties
163
+ Activity.wall Tie.allowed(self, 'read', 'activity')
165
164
  end
166
165
 
167
166
  # The set of activities in the wall profile of this actor, includes the activities
168
- # from the ties of this actor
169
- # TODO: authorization
170
- def wall_profile
171
- Activity.wall ties
167
+ # from the ties of this actor that can be read by user
168
+ #
169
+ def wall_profile(user)
170
+ Activity.wall ties.allowed(user, 'read', 'activity')
172
171
  end
173
172
  end
174
173
 
@@ -1,4 +1,84 @@
1
1
  class Permission < ActiveRecord::Base
2
2
  has_many :relation_permissions, :dependent => :destroy
3
3
  has_many :relations, :through => :relation_permissions
4
+
5
+ ParameterConditions = {
6
+ :table => {
7
+ 'tie' =>
8
+ "ties_as.sender_id = ties.sender_id AND ties_as.receiver_id = ties.receiver_id AND ties_as.relation_id = ties.relation_id",
9
+ 'weak_set' =>
10
+ "ties_as.sender_id = ties.sender_id AND ties_as.receiver_id = ties.receiver_id AND relations.lft BETWEEN relations_as.lft AND relations_as.rgt",
11
+ 'inverse_weak_set' =>
12
+ "ties_as.sender_id = ties.receiver_id AND ties_as.receiver_id = ties.sender_id AND relations.inverse_id = relations_inverse.id AND relations_inverse.lft BETWEEN relations_as.lft AND relations_as.rgt",
13
+ 'group_set' =>
14
+ "ties_as.receiver_id = ties.receiver_id AND ties_as.relation_id = ties.relation_id",
15
+ 'inverse_group_set' =>
16
+ "ties_as.sender_id = ties.receiver_id AND ties_as.relation_id = relations.inverse_id",
17
+ 'weak_group_set' =>
18
+ "ties_as.receiver_id = ties.receiver_id AND relations.lft BETWEEN relations_as.lft AND relations_as.rgt",
19
+ 'inverse_weak_group_set' =>
20
+ "ties_as.sender_id = ties.receiver_id AND relations.inverse_id = relations_inverse.id AND relations_inverse.lft BETWEEN relations_as.lft AND relations_as.rgt"
21
+ },
22
+ :arel => {
23
+ 'tie' => lambda { |as, t|
24
+ # The same sender, receiver and relation
25
+ as[:sender_id].eq(t.sender_id).and(
26
+ as[:receiver_id].eq(t.receiver_id)).and(
27
+ as[:relation_id].eq(t.relation_id))
28
+ },
29
+ 'weak_set' => lambda { |as, t|
30
+ # The same sender and receiver, but a stronger or equal relation
31
+ as[:sender_id].eq(t.sender_id).and(
32
+ as[:receiver_id].eq(t.receiver_id)).and(
33
+ as[:relation_id].in(t.relation.stronger_or_equal.map(&:id)))
34
+ },
35
+ 'inverse_weak_set' => lambda { |as, t|
36
+ # Senders and receivers interchanged, with a stronger or equal relation of the inverse
37
+ as[:sender_id].eq(t.receiver_id).and(
38
+ as[:receiver_id].eq(t.sender_id)).and(
39
+ as[:relation_id].in(Array(t.relation.inverse.try(:stronger_or_equal)).map(&:id)))
40
+ },
41
+ 'group_set' => lambda { |as, t|
42
+ # The same receiver and relation
43
+ as[:receiver_id].eq(t.receiver_id).and(
44
+ as[:relation_id].eq(t.relation_id))
45
+ },
46
+ 'inverse_group_set' => lambda { |as, t|
47
+ # Senders to the common receiver in the same relation
48
+ as[:sender_id].eq(t.receiver_id).and(
49
+ as[:relation_id].eq(t.relation.inverse_id))
50
+ },
51
+ 'weak_group_set' => lambda { |as, t|
52
+ # The same receiver with stronger or equal relations
53
+ as[:receiver_id].eq(t.receiver_id).and(
54
+ as[:relation_id].in(t.relation.stronger_or_equal.map(&:id)))
55
+ },
56
+ 'inverse_weak_group_set' => lambda { |as, t|
57
+ # Senders to the common receiver with stronger or equal relations
58
+ as[:sender_id].eq(t.receiver_id).and(
59
+ as[:relation_id].in(Array(t.relation.inverse.try(:stronger_or_equal)).map(&:id)))
60
+ }
61
+ }
62
+ }
63
+
64
+ class << self
65
+ def parameter_conditions(tie = nil)
66
+ if tie.present?
67
+ ParameterConditions[:arel].inject([]) { |conditions, h|
68
+ # Add the condition 'permissions.parameter = key'
69
+ # to all arel ParameterConditions
70
+ conditions <<
71
+ h.last.call(Tie.arel_table, tie).and(arel_table[:parameter].eq(h.first))
72
+ }.inject(nil){ |result, pc|
73
+ # Join all ParameterConditions with OR
74
+ result.nil? ? pc : result.or(pc)
75
+ }
76
+ else
77
+ ParameterConditions[:table].inject([]){ |result, pc|
78
+ result <<
79
+ sanitize_sql([ "#{ pc.last } AND permissions.parameter = ?", pc.first ])
80
+ }.join(" OR ")
81
+ end
82
+ end
83
+ end
4
84
  end
@@ -25,11 +25,7 @@
25
25
  # sends a friendship_request to B. A is granting the friend relation with B, that is,
26
26
  # friendship_request grants friend relation.
27
27
  #
28
- # == Active relations
29
- # Those relations whose ties support activities. The default scope define active
30
- # relations as those that do not grant other relations, those that are not invitations
31
- # or requests.
32
- #
28
+
33
29
  class Relation < ActiveRecord::Base
34
30
  acts_as_nested_set
35
31
 
@@ -44,7 +40,6 @@ class Relation < ActiveRecord::Base
44
40
 
45
41
  scope :reflexive, where(:reflexive => true)
46
42
  scope :request, where('relations.granted_id IS NOT NULL')
47
- scope :active, where(:granted_id => nil)
48
43
 
49
44
  has_many :relation_permissions, :dependent => :destroy
50
45
  has_many :permissions, :through => :relation_permissions
data/app/models/tie.rb CHANGED
@@ -64,7 +64,6 @@ class Tie < ActiveRecord::Base
64
64
  }
65
65
 
66
66
  scope :pending, includes(:relation) & Relation.request
67
- scope :active, includes(:relation) & Relation.active
68
67
 
69
68
  scope :inverse, lambda { |t|
70
69
  sent_by(t.receiver).
@@ -117,65 +116,58 @@ class Tie < ActiveRecord::Base
117
116
  relation_set(:relations => r).first
118
117
  end
119
118
 
120
- # Access Control
119
+ # The inverse tie
120
+ def inverse
121
+ Tie.inverse(self).first
122
+ end
121
123
 
124
+ # Access Control
125
+
122
126
  scope :with_permissions, lambda { |action, object|
123
- includes(:relation => :permissions).
127
+ joins(:relation => :permissions).
124
128
  where('permissions.action' => action).
125
129
  where('permissions.object' => object)
126
130
  }
127
131
 
128
- scope :parameterized, lambda { |tie|
129
- where(tie_conditions(tie).
130
- or(weak_set_conditions(tie)).
131
- or(group_set_conditions(tie)).
132
- or(weak_group_set_conditions(tie)))
133
- }
134
-
132
+ # Given a given permission (action, object), the access_set are the set of ties that grant that permission.
135
133
  scope :access_set, lambda { |tie, action, object|
136
134
  with_permissions(action, object).
137
- parameterized(tie)
135
+ where(Permission.parameter_conditions(tie))
136
+ }
137
+
138
+ scope :allowed_set, lambda { |action, object|
139
+ query =
140
+ select("DISTINCT ties.*").
141
+ from("ties INNER JOIN relations ON relations.id = ties.relation_id, ties as ties_as INNER JOIN relations AS relations_as ON relations_as.id = ties_as.relation_id INNER JOIN relation_permissions ON relations_as.id = relation_permissions.relation_id INNER JOIN permissions ON permissions.id = relation_permissions.permission_id, relations as relations_inverse").
142
+ where("permissions.action = ?", action).
143
+ where("permissions.object = ?", object)
144
+
145
+ conds = Permission.parameter_conditions
146
+ # FIXME: Patch to support public activities
147
+ if action == 'read' && object == 'activity'
148
+ conds = sanitize_sql([ "( #{ conds } ) OR relations.name = ?", "public" ])
149
+ end
150
+
151
+ query.where(conds)
152
+ }
153
+
154
+ scope :allowed, lambda { |actor, action, object|
155
+ allowed_set(action, object).
156
+ where("ties_as.receiver_id" => Actor_id(actor))
138
157
  }
139
158
 
159
+ def access_set(action, object)
160
+ self.class.access_set(self, action, object)
161
+ end
140
162
 
141
163
  def permissions(user, action, object)
142
- self.class.
143
- sent_by(user).
144
- access_set(self, action, object)
164
+ access_set(action, object).received_by(user)
145
165
  end
146
166
 
147
167
  def permission?(user, action, object)
148
168
  permissions(user, action, object).any?
149
169
  end
150
170
 
151
- class << self
152
- def tie_conditions(t)
153
- arel_table[:sender_id].eq(t.sender_id).and(
154
- arel_table[:receiver_id].eq(t.receiver_id)).and(
155
- arel_table[:relation_id].eq(t.relation_id)).and(
156
- Permission.arel_table[:parameter].eq('tie'))
157
- end
158
-
159
- def weak_set_conditions(t)
160
- arel_table[:sender_id].eq(t.sender_id).and(
161
- arel_table[:receiver_id].eq(t.receiver_id)).and(
162
- arel_table[:relation_id].in(t.relation.stronger_or_equal.all)).and(
163
- Permission.arel_table[:parameter].eq('weak_set'))
164
- end
165
-
166
- def group_set_conditions(t)
167
- arel_table[:receiver_id].eq(t.receiver_id).and(
168
- arel_table[:relation_id].eq(t.relation_id)).and(
169
- Permission.arel_table[:parameter].eq('group_set'))
170
- end
171
-
172
- def weak_group_set_conditions(t)
173
- arel_table[:receiver_id].eq(t.receiver_id).and(
174
- arel_table[:relation_id].in(t.relation.stronger_or_equal.all)).and(
175
- Permission.arel_table[:parameter].eq('weak_group_set'))
176
- end
177
- end
178
-
179
171
  private
180
172
 
181
173
  # Before validation callback
@@ -1,7 +1,6 @@
1
1
  <%= div_for activity, :class => "subactivity" do %>
2
2
  <div class="actor_logo_subactivity">
3
- <%= link_to image_tag(activity.sender_subject.logo.url(),
4
- :size => "30x30",
3
+ <%= link_to image_tag(activity.sender_subject.logo.url(:actor),
5
4
  :alt => activity.sender_subject.name),
6
5
  activity.sender_subject %>
7
6
  </div>