Декларативная авторизация - исключение Catch "Авторизация :: NotAuthorized" - PullRequest
1 голос
/ 28 сентября 2010

В настоящее время я использую декларативную авторизацию в своем приложении и пытаюсь отловить исключения из типа 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)

Ответы [ 2 ]

0 голосов
/ 06 октября 2010

Невозможно отловить исключение при обратном вызове до.Лучший способ, который я нашел для такого рода проверки:

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

Спасибо за помощь

0 голосов
/ 28 сентября 2010

Я бы сказал, что он выходит за пределы блока begin ... rescue и поэтому не пойман спасателем. Попробуйте сделать то же самое на линии 88 вашего контроллера.

Если вы хотите обработать это в процессе проверки, возможно, попробуйте выполнить тест на роли или разрешения пользователя перед созданием объекта, вместо того, чтобы перехватывать исключение, которое будет выдано только при создании.

...