声明性授权 - 捕获“Authorization::NotAuthorized”例外

发布于 2024-09-25 08:50:52 字数 3933 浏览 5 评论 0原文

我目前正在我的应用程序上使用声明性授权,并尝试捕获 Authorization::NotAuthorized 类型的异常。

我有一个有类别的实体。根据角色,用户在创建此实体时可以创建新类别。在我的 :before_validation 回调中,我分配类别并希望能够捕获授权异常,以防他没有权限。

我可以检查它的角色并做出条件指令,但随后必须编写所有角色。

正在抛出异常,但我无法在“新”指令中捕获它。

代码如下:

# Model
before_validation :set_category

def category_name
    @category_name ||= category.name unless category.nil?
    @category_name
end

def category_name=(name)
    name.strip!
    name.downcase!
    @category_name = name
end

def set_category
    if @category_name and not company.blank?
        lookup_category = company.categories.not_deleted.find_by_name(@category_name)
        begin 
            category = lookup_category.blank? ? company.categories.new(:name => @category_name) : lookup_category
        rescue Authorization::NotAuthorized
           errors.add(:category, I18n.t('activerecord.errors.messages.exclusion'))
        end
    end
end

# Controller
def create
    @ticket = current_user.created_tickets.new(params[:ticket])
    if @ticket.save  # Line 88
    ...

异常堆栈跟踪:

Authorization::NotAuthorized (No matching rules found for create for #<User id: 36,..."> (roles [:Requester], privileges [:create], context :categories).):
  /Library/Ruby/Gems/1.8/gems/declarative_authorization-0.4.1/lib/declarative_authorization/authorization.rb:168:in `permit!'
  /Library/Ruby/Gems/1.8/gems/declarative_authorization-0.4.1/lib/declarative_authorization/in_model.rb:131:in `using_access_control'
  /Library/Ruby/Gems/1.8/gems/after_commit-1.0.7/lib/after_commit/connection_adapters.rb:12:in `transaction'
  /Library/Ruby/Gems/1.8/gems/after_commit-1.0.7/lib/after_commit/connection_adapters.rb:12:in `transaction'
  app/controllers/tickets_controller.rb:88:in `create'

调试器进入块内部:

# Debugger
lookup_category = company.categories.not_deleted.find_by_name(@category_name)
(rdb:3) list
[275, 284] in /Users/Pedro/projects/trunk/app/models/ticket.rb
   275    
   276    def set_category
   277      if @category_name and not self.company.blank?
   278        begin
   279          debugger
=> 280          lookup_category = company.categories.not_deleted.find_by_name(@category_name)
   281          self.category = lookup_category.blank? ? company.categories.new(:name => @category_name) : lookup_category
   282        rescue Authorization::NotAuthorized
   283          self.errors.add(:category, I18n.t('activerecord.errors.messages.exclusion'))
   284        end
(rdb:3) n
/Users/Pedro/projects/trunk/app/models/ticket.rb:281
self.category = lookup_category.blank? ? company.categories.new(:name => @category_name) : lookup_category
(rdb:3) list
[276, 285] in /Users/Pedro/projects/trunk/app/models/ticket.rb
   276    def set_category
   277      if @category_name and not self.company.blank?
   278        begin
   279          debugger
   280          lookup_category = company.categories.not_deleted.find_by_name(@category_name)
=> 281          self.category = lookup_category.blank? ? company.categories.new(:name => @category_name) : lookup_category
   282        rescue Authorization::NotAuthorized
   283          self.errors.add(:category, I18n.t('activerecord.errors.messages.exclusion'))
   284        end
   285      end
(rdb:3) n
/Users/Pedro/.gem/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:94
break result if terminator.call(result, object)
(rdb:3) list
[89, 98] in /Users/Pedro/.gem/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb
   89          unless block_given?
   90            send(enumerator) { |callback| callback.call(object) }
   91          else
   92            send(enumerator) do |callback|
   93              result = callback.call(object)
=> 94              break result if terminator.call(result, object)
   95            end
   96          end
   97        end
   98  
(rdb:3)

I'm currently using Declarative Authorization on my application, and trying to catch Exceptions from type Authorization::NotAuthorized.

I have an Entity that has a category. Depending on the role a user can create a new category when creating this entity. At my :before_validation callback I assign the category and want to be able to catch the authorization exception in case he doesn't have permission.

I could check it's role and make a conditional instruction, but then would have to write all the roles.

Exception is being thrown, but I'm not able to catch it, at the "new" instruction.

Code follows:

# Model
before_validation :set_category

def category_name
    @category_name ||= category.name unless category.nil?
    @category_name
end

def category_name=(name)
    name.strip!
    name.downcase!
    @category_name = name
end

def set_category
    if @category_name and not company.blank?
        lookup_category = company.categories.not_deleted.find_by_name(@category_name)
        begin 
            category = lookup_category.blank? ? company.categories.new(:name => @category_name) : lookup_category
        rescue Authorization::NotAuthorized
           errors.add(:category, I18n.t('activerecord.errors.messages.exclusion'))
        end
    end
end

# Controller
def create
    @ticket = current_user.created_tickets.new(params[:ticket])
    if @ticket.save  # Line 88
    ...

Exception stack trace:

Authorization::NotAuthorized (No matching rules found for create for #<User id: 36,..."> (roles [:Requester], privileges [:create], context :categories).):
  /Library/Ruby/Gems/1.8/gems/declarative_authorization-0.4.1/lib/declarative_authorization/authorization.rb:168:in `permit!'
  /Library/Ruby/Gems/1.8/gems/declarative_authorization-0.4.1/lib/declarative_authorization/in_model.rb:131:in `using_access_control'
  /Library/Ruby/Gems/1.8/gems/after_commit-1.0.7/lib/after_commit/connection_adapters.rb:12:in `transaction'
  /Library/Ruby/Gems/1.8/gems/after_commit-1.0.7/lib/after_commit/connection_adapters.rb:12:in `transaction'
  app/controllers/tickets_controller.rb:88:in `create'

Debugger goes inside the block:

# Debugger
lookup_category = company.categories.not_deleted.find_by_name(@category_name)
(rdb:3) list
[275, 284] in /Users/Pedro/projects/trunk/app/models/ticket.rb
   275    
   276    def set_category
   277      if @category_name and not self.company.blank?
   278        begin
   279          debugger
=> 280          lookup_category = company.categories.not_deleted.find_by_name(@category_name)
   281          self.category = lookup_category.blank? ? company.categories.new(:name => @category_name) : lookup_category
   282        rescue Authorization::NotAuthorized
   283          self.errors.add(:category, I18n.t('activerecord.errors.messages.exclusion'))
   284        end
(rdb:3) n
/Users/Pedro/projects/trunk/app/models/ticket.rb:281
self.category = lookup_category.blank? ? company.categories.new(:name => @category_name) : lookup_category
(rdb:3) list
[276, 285] in /Users/Pedro/projects/trunk/app/models/ticket.rb
   276    def set_category
   277      if @category_name and not self.company.blank?
   278        begin
   279          debugger
   280          lookup_category = company.categories.not_deleted.find_by_name(@category_name)
=> 281          self.category = lookup_category.blank? ? company.categories.new(:name => @category_name) : lookup_category
   282        rescue Authorization::NotAuthorized
   283          self.errors.add(:category, I18n.t('activerecord.errors.messages.exclusion'))
   284        end
   285      end
(rdb:3) n
/Users/Pedro/.gem/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:94
break result if terminator.call(result, object)
(rdb:3) list
[89, 98] in /Users/Pedro/.gem/ruby/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb
   89          unless block_given?
   90            send(enumerator) { |callback| callback.call(object) }
   91          else
   92            send(enumerator) do |callback|
   93              result = callback.call(object)
=> 94              break result if terminator.call(result, object)
   95            end
   96          end
   97        end
   98  
(rdb:3)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

还给你自由 2024-10-02 08:50:52

我想说它超出了 begin ...rescue 块,因此没有被救援捕获。尝试在控制器的第 88 行执行相同的救援操作。

如果您想在验证过程中处理此问题,可以尝试在创建对象之前对用户的角色或权限进行测试,而不是捕获仅在创建时抛出的异常。

I'd say that it's breaking outside the begin ... rescue block and therefore not caught by the rescue. Try to do the same rescue on line 88 of your controller.

If you want to handle this in the validation process, maybe try to do a test on the roles or permissions of the user before creating your object instead of catching the exception that will only be thrown on creation.

病女 2024-10-02 08:50:52

不可能在 before 回调中捕获异常。我发现进行此类验证的最佳方法是:

# Model code
begin 
    User.with_permissions_to :create, :categories  # Raises exception if not permitted
    ... do whatever you want
rescue
    ... do whatever you want
end

感谢所有帮助

It's not possible to catch the exception on a before callback. The best way I found to do this kind of validation is:

# Model code
begin 
    User.with_permissions_to :create, :categories  # Raises exception if not permitted
    ... do whatever you want
rescue
    ... do whatever you want
end

Thanks for all the help

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文