назначение ролей в devise/cancan/deviseldap/rolify и использование ldap_param_value

Итог: как я могу назначить роль из ldap сразу после входа пользователя в систему.

Я использую devise/cancan/deviseldap/rolify для аутентификации пользователей, а затем, надеюсь, назначаю роль. Я близок к тому, я думаю, чтобы это заработало. У меня есть собственный инициализатор, который позволяет пользователю войти в приложение, только если у него есть определенный memberOf в его записи ldap.

это работает благодаря любезной помощи человека в этой теме:

проверка групп во время выполнения с devise и devise_ldap_authenticable

Итак, теперь пришло время мне назначить роли, побродив по сети, я решил, что, возможно, лучший способ - это after_create в user.rb от devise. У меня были эти memberOf в config/initializer, но я не мог получить к ним доступ позже, как в user.rb, как описано в следующем, что я пытался сделать в user.rb:

 class User < ActiveRecord::Base
     after_create :assign_role
     ...
     ...
  private
  def assign_role
   puts "Assigning role!"
   member_of = self.ldap_param_value("memberOf")  #get array #i know self here is wrong
   member_of.each do |str|
   if str.include? 'Help Desk Admin'
      self.roles << "admin"
   end
   if str.include? 'Password Manager'
      self.roles << "password_manager"
   end
   if str.include? 'Security'
     self.roles << "security"
   end
   if str.include? 'Help Desk'
     self.roles << "help_desk"
   end
  end

 puts "roles assigned!"
 self.update
end

Самая большая проблема (их много, я все еще новичок в ruby) заключается в том, что у меня есть вызов метода ldap_param_value, и я знаю, что вызывать его для себя неправильно, я получил этот код, работающий в той же строке в config/initializer/customdevise. rb (это для моей проверки всех передних ворот): (я знаю, что мне нужен правильный экземпляр объекта, чтобы получить доступ к ldap_param_value выше, но не уверен, что это такое). Я думал, что это было: Devise::LdapAdapter, но я попробовал это выше, и это все равно не сработало:

Devise::LdapAdapter.ldap_param_value(...)

Для полноты мой config/initializer/customedevise.rb

Devise::LdapAdapter::LdapConnect.class_eval do
  def user_group_test
  member_of = self.ldap_param_value("memberOf") #self works here...
  checkgroups member_of # your group test method  end

 def checkgroups(members)
  retVal = false
  members.each do |str|
    if str.include? 'Help Desk Admin' or str.include? 'Password Manager' or  str.include? 'Security' or str.include? 'Help Desk'
        retVal = true;
    end
  end
  return retVal
end
#    'CN=Password Manager'
#    'CN=Help Desk'
#    'CN=Help Desk Admin'
#    'CN=Security'


def authorized?
DeviseLdapAuthenticatable::Logger.send("Authorizing user #{dn}")
  if !user_group_test
    DeviseLdapAuthenticatable::Logger.send("Not authorized because custom authentication failed.")
    return false
  elsif !authenticated?
    DeviseLdapAuthenticatable::Logger.send("Not authorized because not authenticated.")
    return false
  elsif !in_required_groups?
    DeviseLdapAuthenticatable::Logger.send("Not authorized because not in required groups.")
    return false
  elsif !has_required_attribute?
    DeviseLdapAuthenticatable::Logger.send("Not authorized because does not have required attribute.")
    return false
  else
    return true
  end
 end
end

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

en:
  devise:
   confirmations:
    confirmed: "Your account was successfully confirmed. You are now signed in."
    send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
    send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
   failure:
     already_authenticated: "You are already signed in."
     inactive: "Your account was not activated yet."
     invalid: "Invalid email or password.  Or not a member of the correct group"

      ..etc...

person Codejoy    schedule 11.07.2013    source источник
comment
Я могу понять, что вы пытаетесь сделать. Но я не понимаю, как/почему вы используете здесь LDAP.   -  person beck03076    schedule 11.07.2013
comment
потому что мы аутентифицируемся по ldap, а роли хранятся в ldap. Активный каталог, чтобы быть более конкретным.   -  person Codejoy    schedule 11.07.2013
comment
Отлично... Я сохранил свои роли в таблице mysql. Я поделюсь кодом, который это делает. Тогда разница между вами и мной должна заключаться в механизмах поиска ролей. Хотите объяснить, почему роли хранятся в LDAP?   -  person beck03076    schedule 11.07.2013
comment
Ну, я думаю, что механизмы поиска ролей здесь почти ключевые. Хотя роли есть, потому что я создаю сайт для замены старого сайта... этот старый сайт делал все в AD. Чтобы у пользователей был доступ к новому сайту, я хочу, чтобы он был прозрачным: они входят в систему, и их роли переходят.   -  person Codejoy    schedule 11.07.2013


Ответы (1)


Это просто,

  1. Таблица Permissions будет содержать все модели и действия, которые могут быть выполнены пользователями.
  2. Разрешения HABTM Users и Users HABTM Permissions
  3. Роли has_many пользователей, пользователь принадлежит роли
  4. Роли Разрешения и разрешения HABTM Роли HABTM
  5. Если вы установите все вышеперечисленные ассоциации и на основе идентификатора current_user, вы можете получить роль пользователя и получить его разрешения, и эти разрешения будут созданы в классе возможностей следующим методом:

         def initialize(user)   
            user.role.permissions.each do |permission|
              if permission.subject_class == "all"
                can permission.action.to_sym, permission.subject_class.to_sym
              else
                can permission.action.to_sym, permission.subject_class.constantize
            end
          end
         end
    

Эта ссылка показывает, как это сделать,

http://blog.joshsoftware.com/2012/10/23/dynamic-roles-and-permissions-using-cancan/

person beck03076    schedule 11.07.2013
comment
вау там много всего. Я действительно думаю, что мне просто нужно получить роли ldap, а затем сохранить их в базе данных. Убедившись, что в моем application.yml настроены роли, которые я сохраняю в базе данных (после прочтения и тестирования по сравнению с тем, что было найдено в ldap), и я планировал сделать это во время создания пользователя... моя самая большая проблема просто не иметь доступ к ролям из ldap во время after_create - person Codejoy; 11.07.2013
comment
Я проголосовал за это, потому что это был хороший ответ, но я не принял его в качестве ответа, потому что он не дошел до сути моей конкретной проблемы, связанной с получением memberOf из ldap где-то, что НЕ было конфигурацией/инициализаторами. - person Codejoy; 12.07.2013