- 1 files added/modified
- 2 modifications
- 2.1 app/helpers/common/ui/entity_display_helper.rb
- 2.2 app/helpers/groups/permissions_helper.rb
- 2.3 app/models/discussion/post.rb
- 2.4 app/models/user.rb
- 2.5 app/views/common/posts/table/_reply.html.haml
- 2.6 app/views/common/posts/table/_reply_row.html.haml
- 2.7 app/views/groups/permissions/index.html.haml
- 2.8 config/permissions.rb
- 3 Example traces
- 4 debugging in console
- 5 Status of the db after the anonymous/blue postings
- 6 to fix
Branch: github.com/riseuplabs/Crabgrass-Core/tr...
In this case anonymous delegation means that a user can post a comment as anonymous.
Only group and network context anonymous posts are currently supported, what means that pages must be owned by a group/network and the user must be in the group.
The main method implemented is “user.may_act_as?”
When the user choose to post as anonymous, “user_id = 0” and the user id is not stored in the post. However, the columns last_seen_at and last_updated in page register the user id.
With this feature it’s not possible to create pages (wiki, pads, galleries) as anonymous user
files added/modified¶
app/helpers/common/ui/entity_display_helper.rb
app/helpers/groups/permissions_helper.rb
app/models/discussion/post.rb
app/models/user.rb
app/views/common/posts/table/_reply_row.html.haml
app/views/groups/permissions/index.html.haml
config/permissions.rb
app/views/common/posts/table/_reply.html.haml
# why removing group_setting? (is still in master)
app/models/group.rb
app/models/group_setting.rb
db/schema.rb
test/fixtures/group_settings.yml
modifications¶
app/helpers/common/ui/entity_display_helper.rb¶
display, title = if entity.nil?
- [:unknown.t, nil]
+ [:anonymous.t, nil]
+ def author_selection_tag(element_id, context)
+ if current_user.may_act_as?(:user => 0, :context => context)
+ options = options_for_select([[current_user.name, current_user.id], [:anonymous.t,0]])
+ select_tag('author_selector', options, :onchange => "$('#{element_id}').value=this.value;")
+ else
+ author_style = "background-image: url(#{avatar_url_for(current_user,'small')})"
+ content_tag(:div, :class => 'author', :style => author_style) do
+ content_tag(:div, :class => 'username') do
+ display_entity(current_user)
+ end
+ end
app/helpers/groups/permissions_helper.rb¶
+ def allow_anonymous_content_checkbox(form)
+ form.row do |r|
+ r.input castle_gate_tag(@group, :post_anonymously, @holders, :label => @group.gate(:post_anonymou~
+ r.info @group.gate(:post_anonymously).info
+ end
+ end
app/models/discussion/post.rb¶
- validates_presence_of :user, :body
+ validates_presence_of :body
- # user -- the user creating the post (optional)
+ # user -- the user creating the post
+ # group -- the context under which this post is created.
+ # user_id -- set if the user to show on the post is different than the user making the post (optional)
+ # group_id -- set a group to be the author of the post (optional)
def self.create!(*args, &block)
user = nil
+ group = nil
page = nil
+ # parse the args
args.each do |arg|
user = arg if arg.is_a? User
+ group = arg if arg.is_a? Group
- end
- if discussion
+ group ||= page.owner if page.owner_type == 'Group'
+ elsif discussion
attributes[:discussion] = discussion
+ else
+ raise ArgumentError.new('discussion required')
end
- if user
- attributes[:user] = user
+
+ # ensure that there is a user or a group, and that the current_user has
+ # permission to post as this user or group.
+ if attributes[:user_id].any? || attributes[:group_id].any?
+ if attributes[:user_id].any? && !user.may_act_as?(:user => attributes[:user_id], :context => ~
+ raise PermissionDenied.new('may not post as that user')
+ elsif attributes[:group_id].any? && !user.may_act_as?(:group => attributes[:group_id], :conte~
+ raise PermissionDenied.new('may not post as that group')
+ end
+ else
+ attributes[:user_id] = user.id
+
+ # create the post
app/models/user.rb¶
+ #
+ # may this user act as another user, or even another group?
+ #
+ # In other words, may this user be 'anonymous' or take on the identity
+ # of someone else when creating posts or edits?
+ #
+ # supported options:
+ #
+ # :user -- may self act as this user?
+ # (if :user => 0, this means anonymous)
+ #
+ # :group -- may self act as this group?
+ # :context -- what entity is the context for this request.
+ # the context determines what is possible.
+ #
+ def may_act_as?(options={})
+ user, group, context = options[:user], options[:group], options[:context]
+ if context.is_a? Group
+ if user.to_s == "0"
+ context.access?(self => :post_anonymously)
+ elsif user && user.id == self.id
+ true
+ elsif context.is_a? Network
+ if self.member_of?(group) && group.member_of?(context)
+ true
+ end
+ else
+ false # only group and network context anonymous posts are currently supported
+ end
+ end
app/views/common/posts/table/_reply.html.haml¶
- %td.post_author
- %div.author{:style => author_style}
- %div.username= display_entity(current_user)
- %td{:class => 'post_body'}
- - if local_assigns[:reply_body]
- = local_assigns[:reply_body]
- - else
- = render :partial => 'common/posts/table/reply_body', :locals => local_assigns
+ = render :partial => 'common/posts/table/reply_row', :locals => local_assigns
+ -# %td.post_author
+ -# = author_selection
+ -# -# %div.author{:style => author_style}
+ -# -# %div.username= display_entity(current_user)
+ -# -# %div.date
+ -# %td.post_body
+ -# -# i don't think this is used anywhere... ?
+ -# -# - if local_assigns[:reply_body]
+ -# -# = local_assigns[:reply_body]
+ -# -# - else
+ -# = render :partial => 'common/posts/table/reply_body', :locals => local_assigns
app/views/common/posts/table/_reply_row.html.haml¶
+-# requires:
+-# create_url -- url to send the action to
+-# options:
+-# last_id -- set in_reply_to_id, which currently is just used for helping
+-# to generate the activity feed.
+-# remote -- if not nil, generate an ajax form.
+-#
+
+- remote = local_assigns[:remote] || false
+- form = remote ? method(:remote_form_for) : method(:form_for)
+- form_options = {:url => create_url, :loading => show_spinner('post')}
+%td.post_author
+ = author_selection_tag('user_id', @group || @user || @context.try(:entity))
+%td.post_body
+ - form.call(:post, @post, form_options) do |f|
+ = hidden_field_tag('post[user_id]', '', :id => 'user_id')
+ = f.text_area :body, :rows => 8, :class => 'input-xlarge'
+ .buttons
+ .float_left= formatting_reference_link
+ - if remote
+ = spinner('post')
+ = submit_tag :post_message.t, :name => 'post_message', :class => 'btn btn-primary'
app/views/groups/permissions/index.html.haml¶
+ - f.heading :content.t
+ - allow_anonymous_content_checkbox(f)
config/permissions.rb¶
+ gate 13, :post_anonymously,
+ :label => 'Anonymous Posts',
+ :info => 'Are members allowed to post anonymously?'
+
protected
def create_permissions
grant_access! self => :all
+ revoke_access! self => :post_anonymously
if council?
Example traces¶
Request as user blue the page
localhost:3000/rainbow/scipit-ligula-a-...
view¶
Processing DiscussionPageController#show (for 78.249.69.26 at 2012-07-08 19:28:03) [GET]
Parameters: {"id"=>nil, "_context"=>"rainbow", "_page"=>"scipit-ligula-a-nisi-quisque-augu+95", "controller"=>"discussion_page", "action"=>"show", "path"=>[]}
...
User Update (0.3ms) UPDATE `users` SET `last_seen_at` = '2012-07-08 10:28:03', `updated_at` = '2012-07-08 10:28:03' WHERE `id` = 4
...
DiscussionPage Columns (0.9ms) SHOW FIELDS FROM `pages`
UserParticipation Columns (0.5ms) SHOW FIELDS FROM `user_participations`
UserParticipation Load (0.2ms) SELECT * FROM `user_participations` WHERE (`user_participations`.`user_id` = 4) AND (`user_participations`.page_id = 95) LIMIT 1
...
Post Load (8.4ms) SELECT * FROM `posts` WHERE (`posts`.`discussion_id` = 24) AND (deleted_at IS NULL) ORDER BY created_at ASC LIMIT 0, 30
post as anonymous¶
Processing Pages::PostsController#create (for 78.249.69.26 at 2012-07-08 19:21:47) [POST]
Parameters: {"page_id"=>"95", "authenticity_token"=>"DeXhuCJSMH3mMPelHX5mtvDPOic1rY57un8ay3nX+xo=", "post"=>{"user_id"=>"0", "body"=>"anonymous"}, "controller"=>"pages/posts", "action"=>"create", "post_message"=>"Post Message"}
...
Post Create (0.3ms) INSERT INTO `posts` (`created_at`, `updated_at`, `user_id`, `page_terms_id`, `type`, `discussion_id`, `body`, `body_html`, `deleted_at`) VALUES('2012-07-08 10:21:50', '2012-07-08 10:21:50', 0, 95, NULL, 24, 'anonymous', '<p>anonymous</p>', NULL)
...
DiscussionPage Update (0.2ms) UPDATE `pages` SET `posts_count` = 7 WHERE `id` = 95
...
Discussion Update (0.2ms) UPDATE `discussions` SET `posts_count` = 7, `last_post_id` = 15, `replied_by_id` = 0, `replied_at` = '2012-07-08 10:21:50' WHERE `id` = 24
...
PageHistory::AddComment Create (0.2ms) INSERT INTO `page_histories` (`created_at`, `notification_digest_sent_at`, `page_id`, `user_id`, `details`, `notification_sent_at`, `type`, `object_id`, `object_type`) VALUES('2012-07-08 10:21:50', NULL, 95, 4, NULL, NULL, 'AddComment', 15, 'Post')
Page Update (2.1ms) UPDATE `pages` SET updated_at = '2012-07-08 10:21:50' WHERE (id = 95)
...
UserParticipation Update (0.6ms) UPDATE `user_participations` SET viewed = 0 WHERE (`user_participations`.page_id = 95)
SQL (0.1ms) BEGIN
UserParticipation Update (0.2ms) UPDATE `user_participations` SET `changed_at` = '2012-07-08 10:21:50', `viewed_at` = '2012-07-08 10:21:50' WHERE `id` = 315
post as user blue¶
Processing Pages::PostsController#create (for 78.249.69.26 at 2012-07-08 19:14:36) [POST]
Parameters: {"page_id"=>"95", "authenticity_token"=>"DeXhuCJSMH3mMPelHX5mtvDPOic1rY57un8ay3nX+xo=", "post"=>{"user_id"=>"", "body"=>"blue"}, "controller"=>"pages/posts", "action"=>"create", "post_message"=>"Post Message"}
...
Post Create (0.3ms) INSERT INTO `posts` (`created_at`, `updated_at`, `user_id`, `page_terms_id`, `type`, `discussion_id`, `body`, `body_html`, `deleted_at`) VALUES('2012-07-08 10:14:39', '2012-07-08 10:14:39', 4, 95, NULL, 24, 'blue', '<p>blue</p>', NULL)
...
DiscussionPage Update (0.3ms) UPDATE `pages` SET `posts_count` = 6 WHERE `id` = 95
...
Discussion Update (0.4ms) UPDATE `discussions` SET `posts_count` = 6, `last_post_id` = 14, `replied_by_id` = 4, `replied_at` = '2012-07-08 10:14:39' WHERE `id` = 24
...
PageHistory::AddComment Create (0.3ms) INSERT INTO `page_histories` (`created_at`, `notification_digest_sent_at`, `page_id`, `user_id`, `details`, `notification_sent_at`, `type`, `object_id`, `object_type`) VALUES('2012-07-08 10:14:39', NULL, 95, 4, NULL, NULL, 'AddComment', 14, 'Post')
Page Update (0.2ms) UPDATE `pages` SET updated_at = '2012-07-08 10:14:39' WHERE (id = 95)
...
UserParticipation Update (0.6ms) UPDATE `user_participations` SET viewed = 0 WHERE (`user_participations`.page_id = 95)
SQL (0.1ms) BEGIN
UserParticipation Update (0.2ms) UPDATE `user_participations` SET `changed_at` = '2012-07-08 10:14:39', `viewed_at` = '2012-07-08 10:14:39' WHERE `id` = 315
debugging in console¶
/home/jula/crabgrass-core-delegation/app/controllers/pages/posts_controller.rb:22
current_user.updated(@page)
(rdb:1) p @post
#<Post id: 12, user_id: 0, discussion_id: 24, body: "more anonymous", body_html: "<p>more anonymous</p>", created_at: "2012-07-08 08:32:51", updated_at: "2012-07-08 08:32:51", deleted_at: nil, type: nil, page_terms_id: 95>
#<DiscussionPage id: 95, title: "scipit ligula a nisi. Quisque augu", created_at: "2012-07-01 15:51:38", updated_at: "2012-07-08 08:33:49", resolved: false, public: true, created_by_id: nil, updated_by_id: 4, summary: "Sed blandit elit a libero. Suspendisse potenti. Don...", type: "DiscussionPage", message_count: 0, data_id: nil, data_type: nil, contributors_count: 0, posts_count: 4, name: nil, updated_by_login: "blue", created_by_login: nil, flow: nil, stars_count: 1, views_count: 61, owner_id: 3, owner_type: "Group", owner_name: "rainbow", is_image: nil, is_audio: nil, is_video: nil, is_document: nil, site_id: nil, happens_at: nil, cover_id: nil>
Status of the db after the anonymous/blue postings¶
mysql> select user_id from posts where discussion_id=24;
+---------+
| user_id |
+---------+
| 4 |
| 0 |
| 4 |
| 0 |
| 0 |
+---------+
mysql> select * from users where id=0;
Empty set (0.00 sec)
to fix¶
- some discussion pages appear as owned by anonymous when it’s not possibe a page owner is anonymous (only the post)
- after posting is needed to refresh the page to see the dropbox where u can choose to publish as anonymous
- No defined method group_settings when trying to create a page as a group. Instead it’s possible to create it as a user and :
http://localhost:3000/pages/new/rainbow
NoMethodError in Pages/create#new
Showing app/views/pages/create/_choose_page_class.html.haml where line #10 raised:
undefined method `group_setting' for #<Group:0xb47369dc>
Extracted source (around line #10):
7: = I18n.t(:page_added_to_group, :group_type => @group.group_type.downcase, :group_name => content_tag(:b, @group.display_name))
8:
9: = column_layout 2, page_creation_links, :class => 'layout'
Trace of template inclusion: app/views/pages/create/new.html.haml
RAILS_ROOT: /home/jula/crabgrass-core-delegation
Application Trace | Framework Trace | Full Trace
/home/jula/.rbenv/versions/1.8.7-p358/lib/ruby/gems/1.8/gems/activerecord-2.3.14/lib/active_record/attribute_methods.rb:260:in `method_missing'
/home/jula/crabgrass-core-delegation/app/models/site.rb:164:in `tools_for'
/home/jula/crabgrass-core-delegation/app/helpers/common/page/form_helper.rb:23:in `tree_of_page_types'
/home/jula/crabgrass-core-delegation/app/helpers/pages/creation_helper.rb:21:in `page_creation_links'
/home/jula/crabgrass-core-delegation/app/views/pages/create/_choose_page_class.html.haml:10:in `_run_haml_app47views47pages47create47_choose_page_class46html46haml_locals_choose_page_class_object'
/home/jula/crabgrass-core-delegation/app/views/pages/create/new.html.haml:4:in `_run_haml_app47views47pages47create47new46html46haml'
/home/jula/crabgrass-core-delegation/app/controllers/pages/create_controller.rb:99:in `render_new_template'
/home/jula/crabgrass-core-delegation/app/controllers/pages/create_controller.rb:34:in `new'
Request
Parameters:
{"owner"=>"rainbow"}