рельсы: проблема безопасности массового назначения с отношениями "принадлежат" - PullRequest
5 голосов
/ 29 января 2010

Я перечитывал вопросы безопасности рельсов, и меня больше всего беспокоит массовое назначение. Мое приложение использует attr_accessible, однако я не уверен, что знаю, как лучше всего обрабатывать открытые отношения. Давайте предположим, что у нас есть базовый сайт создания / владения контентом. Пользователь может создавать сообщения в блоге и иметь одну категорию, связанную с этим сообщением.

Итак, у меня есть три модели:

  • Пользователь
  • post: принадлежит пользователю и категории
  • категория: принадлежит пользователю

Я разрешаю массовое назначение для category_id, чтобы пользователь мог обнулить его, изменить его на одну из своих категорий или с помощью массового назначения, я полагаю, они могли бы изменить его на чужую категорию. Вот где я немного не уверен насчет того, как лучше поступить.

Ресурсы, которые я исследовал (в частности, railscast # 178 и resource , который был предоставлен этим Railscast), оба упоминают, что ассоциация не должна быть назначаемой по массе, что делает смысл. Я просто не уверен, как еще разрешить пользователю изменять то, что категория из записи было бы грубым способом.

Есть идеи, как лучше всего это решить? Я смотрю на это неправильно?

ОБНОВЛЕНИЕ : Надеюсь, я проясню кое-что еще.

Допустим, я в Post, мне нужно что-то вроде следующего:

def create
  @post = Post.new(params[:category])

  @post.user_id = current_user.id

  # CHECK HERE IF REQUESTED CATEGORY_ID IS OWNED BY USER

  # continue on as normal here
end

Это похоже на большую работу? Мне нужно было бы проверить это на каждом контроллере как в обновлении, так и в создании действия. Имейте в виду, что существует не только одно отношение "принадлежат_".

Ответы [ 2 ]

5 голосов
/ 29 января 2010

Ваш пользователь может изменить его через какую-либо форму редактирования, я полагаю.

Исходя из этого, Mass Assignment действительно предназначен для гнусных типов, которые стремятся связываться с вашим приложением с помощью таких вещей, как curl. Я называю их кудрявыми детишками.

Все это говорит, если вы используете attr_protected - (здесь вы помещаете поля, которые вы не хотите, чтобы они меняли) или любимые для ребенка attr_accessible (поля, которые можно менять).

Вы услышите аргументы для обоих, но если вы используете attr_protected :user_id в своей модели, а затем в вашем действии CategoryController # create, вы можете сделать что-то вроде

def create
  @category = Category.new(params[:category])

  @category.user_id = current_user.id
  respond_to do |format|
....#continue on as normal here
end
0 голосов
/ 29 января 2010

ОК, так что немного искал и, наконец, придумал что-то подходящее для меня. Мне нравится держать логику вне контроллеров, где это возможно, поэтому это решение основано на моделях:

# Post.rb
validates_each :asset_category_id do |record, attr, value|
  self.validates_associated_permission(record, attr, value)
end

# This can obviously be put in a base class/utility class of some sort.
def self.validates_associated_permission(record, attr, value)
  return if value.blank?
  class_string = attr.to_s.gsub(/_id$/, '')
  klass = class_string.camelize.constantize

  # Check here that the associated record is the users
  # I'm leaving this part as pseudo code as everyone's auth code is
  # unique.
  if klass.find_by_id(value).can_write(current_user)
    record.errors.add attr, 'cannot be found.'
  end
end

Я также обнаружил, что у rails 3.0 будет лучший способ указать это вместо 3 строк, необходимых для универсального validates_each.

http://ryandaigle.com/articles/2009/8/11/what-s-new-in-edge-rails-independent-model-validators

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...