Ruby/Rails,Gate子句语法来强制执行安全策略



我有一个难题要解决。

我想复制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

为什么不做这样的事情?

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

考虑分离您的关注点:我会通过创建一个单独的函数来处理授权来实现这一点。

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_usercurrent_user_levelCar的上下文之外是有意义的,并且您可能希望在其他地方重用它,那么您可以进一步将身份验证检查方法移动到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

最新更新