Ruby / Rails, синтаксис предложения Gate для реализации политики безопасности - PullRequest
0 голосов
/ 08 ноября 2019

У меня сложная проблема, которую нужно решить.

Я хотел бы повторить, результаты методов title_with_if_statement, но с использованием синтаксиса, используемого в методе title. Тем не менее, я не знаю, что положить в enforce_policy_to_level() метод для достижения этой цели.

Я могу сделать 'title_less_readable', но я считаю, что метод title гораздо более читабелен, так как политика находится на самом верху, и так как я буду делать это для сотен методов, я хочу, чтобы он оставался СУХИМЫМ и

Любой совет?

Это вообще возможно? Это в основном before_action, но использует собственные результаты метода.

class Car

  def title
    enforce_policy_to_level(1)
   # Code that returns the "Car Title" string
   "Car Title"
  end

  def title_less_readable
    # Code that returns "Car Title" string
    content = "Car Title"
    return secure_text(content) unless authorized_to_level?(1)
    content
  end

  def title_with_if_statement
    # Code that returns the "Car Title" string
    content = "Car Title"
    if authorized_to_level?(1)
      content
    else
      secure_text(content)
    end
  end

  private

  def enforce_policy_to_level(level)
    # Return from title method with the secured result of title method
    # if it's not authorized. In this example it would be secure_text('Car Title')
    # which output return '---------'
    # If if authorized, just continue with how title method would normally return
  end

  def authorized_to_level?(level)
    current_user_level = 1 # Dynamic from user record
    current_user_level >= level
  end

  def secure_text(text)
    'X' * text.length
  end

end

Ответы [ 2 ]

0 голосов
/ 09 ноября 2019

Подумайте о том, чтобы разделить ваши проблемы: я бы подошел к этому, создав отдельную функцию, которая обрабатывает авторизацию.

module AuthorizedText
  module_function

  def secure_text(text, authorized)
    return authorized ? text : 'X' * text.length
  end
end

Вызовите это в Car следующим образом:

AuthorizedText.secure_text("Car Title", authorized_to_level(1))

Вы можете сократить это с помощью удобного метода:

def secure(level, text)
  AuthorizedText.secure_text(text, authorized_to_level(level))
end

, чтобы ваш метод car_title выглядел так:

def car_title
  secure(1, "Car Title")
end

Вы могли бы обобщить обертку метода следующим образом:определение метода класса, который позволил бы вам сделать что-то вроде

def car_title
  "Car Title"
end

secure :car_title

Но я бы назвал это чрезмерно сложным и в конечном итоге менее читабельным для всех, кто не является вами (включая вас, вероятно, через 8 месяцев!)). Я бы не пытался быть таким причудливым, каким бы забавным это ни было.

Кроме того, если current_user и current_user_level имеют смысл вне контекста Car, и вы можете использовать это повторнов другом месте вы можете пойти дальше, переместив методы проверки подлинности в AuthorizedText, если это уместно:

module AuthorizedText
  module_function

  def secure_text(text, user, level = 0)
    return authorized?(user, level) ? text : 'X' * text.length
  end

  def authorized?(user, level)
    # for example; I don't know what your user object looks like
    user.level >= level
  end
end
0 голосов
/ 09 ноября 2019

Почему бы просто не так?

  def title
    enforce_policy_to_level(1) do
      "Car Title"
    end
  end

  private

  def enforce_policy_to_level(level, &block)
    if authorized_to_level?(level)
      secure_txt yield
    else
      yield
    end
  end
...