inossidabile / protector

Comfortable (seriously) white-list security restrictions for models on a field level
MIT License
270 stars 31 forks source link

Relation scope overriding #33

Closed AlexanderPavlenko closed 10 years ago

AlexanderPavlenko commented 10 years ago

Protector scope in protected model ArticleAttachment:

scope {
  article_id = ArticleAttachment.arel_table[:article_id]
  allowed_ids = user.shared_articles.pluck(:id)
  ArticleAttachment.where(article_id.eq(nil).or(article_id.in(allowed_ids)))
}

Request:

> ArticleAttachment.where(id: uploaded_attachments).size
  CACHE (0.1ms)  SELECT COUNT(*) FROM "article_attachments" WHERE "article_attachments"."id" IN (9)
=> 1

> ArticleAttachment.restrict!(protector_subject).where(id: uploaded_attachments).size
  CACHE (0.0ms)  SELECT COUNT(*) FROM "article_attachments" WHERE (("article_attachments"."article_id" IS NULL OR "article_attachments"."article_id" IN (2, 3, 6, 5, 4)))
=> 9

Without Protector it works fine:

> ArticleAttachment.where(article_id.eq(nil).or(article_id.in([1,2,3]))).to_sql
=> "SELECT \"article_attachments\".* FROM \"article_attachments\"  WHERE ((\"article_attachments\".\"article_id\" IS NULL OR \"article_attachments\".\"article_id\" IN (1, 2, 3)))"

> ArticleAttachment.where(article_id.eq(nil).or(article_id.in([1,2,3]))).where(id: [4]).to_sql
=> "SELECT \"article_attachments\".* FROM \"article_attachments\"  WHERE \"article_attachments\".\"id\" IN (4) AND ((\"article_attachments\".\"article_id\" IS NULL OR \"article_attachments\".\"article_id\" IN (1, 2, 3)))"
inossidabile commented 10 years ago

ArticleAttachment.where(article_id.eq(nil).or(article_id.in(allowed_ids))) you misuse the scope thing. You should not refer to class directly. Start from where.