ActiveLdap::Base#find の :filter オプション

ActiveLdapLDAP へのオブジェクト指向インターフェースを提供する Ruby ライブラリ。ActiveRecord ライクに LDAP を扱うことができます。

ActiveLdap::Base#find は :filter オプションで LDAP エントリの検索条件を指定します。ActiveRecord::Base#find の :conditions に相当するオプションです。

User が ActiveLdap のサブクラスだとして、使い方は以下のようにします。

User.find :all, :filter => '(uid=tashen)'
#=> [#<User objectClass:...>]

で、実はこのオプション色々な形式を使えたりします(これを司るのが ActiveLdap::Adapter::Base#parse_filter です)。

以下の記述では ActiveLdap のログ出力先を stdout にして、フィルタの変化をコンソール上に表示します。

文字列の場合

そのままフィルタ文字列として扱います。

irb> User.find :all, :filter => '(uid=tashen)'
  LDAP: search (0.7ms): {:filter=>"(&(uid=tashen)(&(objectClass=top)(objectClass=person)(objectClass=posixAccount)))", :attributes=>[], :scope=>:sub, :base=>"ou=Users,dc=example,dc=com"}
=> [#<User objectClass:<top, posixAccount, person>, ..]

注意点としてはフィルタ文字列をエスケープしてくれないこと。

配列(Array)の場合

パースしてくれて、エスケープもしてくれるです

irb> User.find :all, :filter => ['uid', 'tashen']
  LDAP: search (1.4ms): {:filter=>"(&(uid=tashen)(&(objectClass=top)(objectClass=person)(objectClass=posixAccount)))", :attributes=>[], :scope=>:sub, :base=>"ou=Users,dc=example,dc=com"}
=> [#<User objectClass:<top, posixAccount, person>, ..]

or する

irb> User.find :all, :filter => [:or, ['uid', 'tashen'], ['uid', 'hoge']]
  LDAP: search (1.4ms): {:filter=>"(&(|(uid=tashen)(uid=hoge))(&(objectClass=top)(objectClass=person)(objectClass=posixAccount)))", :scope=>:sub, :attributes=>[], :base=>"ou=Users,dc=example,dc=com"}
=> [#<User objectClass:<top, posixAccount, person>, ..]

and する

irb> User.find :all, :filter => [:and, ['uid', 'tashen'], ['uid', 'hoge']]
  LDAP: search (1.0ms): {:filter=>"(&(&(uid=tashen)(uid=hoge))(&(objectClass=top)(objectClass=person)(objectClass=posixAccount)))", :scope=>:sub, :attributes=>[], :base=>"ou=Users,dc=example,dc=com"}
=> []

否定

irb> User.find :all, :filter => [:not, ['uid', 'tashen']]
  LDAP: search (1.4ms): {:filter=>"(&(!(uid=tashen))(&(objectClass=top)(objectClass=person)(objectClass=posixAccount)))", :scope=>:sub, :attributes=>[], :base=>"ou=Users,dc=example,dc=com"}
=> [#<User objectClass:<top, posixAccount, person>, ..]

組み合わせ

irb> User.find :all, :filter => [:or, [:not, ['uid', 'hoge']], ['uid', 'tashen']]
  LDAP: search (1.4ms): {:filter=>"(&(|(!(uid=hoge))(uid=tashen))(&(objectClass=top)(objectClass=person)(objectClass=posixAccount)))", :scope=>:sub, :attributes=>[], :base=>"ou=Users,dc=example,dc=com"}
=> [#<User objectClass:<top, posixAccount, person>, ..]

プログラムでフィルタ組み立てるのには一番便利かも。

ハッシュ(Hash)の場合

Hash のみだと柔軟性に欠けるので Array と掛け合わせるのが良さそう。

見やすいけれど、複雑なことをやるなら Array の方が一貫性があっていいと思う。

irb> User.find :all, :filter => {:uid => 'tashen'}
  LDAP: search (1.1ms): {:filter=>"(&(uid=tashen)(&(objectClass=top)(objectClass=person)(objectClass=posixAccount)))", :scope=>:sub, :attributes=>[], :base=>"ou=Users,dc=example,dc=com"}
irb> User.find :all, :filter => [:or, {:uid => ['tashen', 'hoge']}]
  LDAP: search (1.1ms): {:filter=>"(&(|(uid=tashen)(uid=hoge))(&(objectClass=top)(objectClass=person)(objectClass=posixAccount)))", :scope=>:sub, :attributes=>[], :base=>"ou=Users,dc=example,dc=com"}