0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

pythonでLDAPにデータの追加取得をする(WriterとReader編)

Posted at

はじめに

前回はLDAPの追加と取得を行いました。今回は、WriterとReaderを使用した追加と取得の方法をまとめます。

環境

  • python:3.6.5
  • ldap3:2.7
  • イメージ:osixia/openldap

LDAP操作

Readerを使用したLDAPの読み込み

ldap3には色々な機能を持ったReaderクラスがあります。それを使用してLDAPの情報を取得します。Readerにはコネクションとオブジェクトとcn(検索パス)が必要になります。例は基本的に上から順に続きものとして記載しています。

オブジェクトの生成

オブジェクトはObjectDefクラスに対象のオブジェクト名とコネクションを渡して生成します。今回は、cnの値を取りたいためinetOrgPersonを指定します。ouを取得したいときはorganizationalUnitなど取得したい対象を指定します。

main.py

from ldap3 import Server, Connection, ObjectDef, Reader

server = Server('localhost')
conn = Connection(server, 'cn=admin,dc=sample-ldap',  password='LdapPass')
result = conn.bind()

# inetOrgPersonのオブジェクト生成
obj_cn_name = ObjectDef('inetOrgPerson', conn)

Readerの生成

先ほど生成したオブジェクトとコネクション、検索パスを与えてReaderを生成します。この時に与える検索パスにより、どの階層から情報を取得できるかを指定できます。ここではReaderの生成だけで検索していないので値は入っていません。

main.py

# リーダーの生成
data_reader = Reader(conn, obj_cn_name, 'ou=sample-unit,dc=sample-component,dc=sample-ldap')

LDAPの値の取得

LDAPの値の配下をリストで取得

リーダーのsearch()を使用することでLDAP値のリストを取得することができます。

main.py

# ここで検索をする
data = data_reader.search()

# 全アイテムが取れる
print(data)

結果


[DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T20:50:15.470086
    cn: sample-name
    objectClass: inetOrgPerson
    sn: sample1
        sample2
    st: test2
, DN: cn=sample-name1,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T20:50:15.478084
    cn: sample-name1
    objectClass: inetOrgPerson
    sn: sample
]

結果を見るとReaderに指定したou=sample-unit,dc=sample-component,dc=sample-ldap以下のcnが全て取得できていることがわかります。さらにそれぞれの属性値であるsnとstが取得できています。

属性による検索データの取得

search()に属性の文字列を入れて属性値のあるデータを取得します。例ではstを与えており、LDAPの情報は先ほどと同じなのでcn: sample-nameが取れるはずです。

main.py

# 検索条件を指定する
data = data_reader.search('st')
print(data)

結果


DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T20:50:15.470086
    cn: sample-name
    objectClass: inetOrgPerson
    sn: sample1
        sample2
    st: test2

結果を見ると予想した通りsample-nameのcnが取れました。

json形式で取得する

リーダーのentry_to_json()を使用することでLDAPの値をjson形式の文字列に変換して取得できる機能があります。

main.py

# json形式で取得できる
json_str = data[0].entry_to_json()
print(json_str)
print(type(json_str))

結果


{
    "attributes": {
        "st": [
            "test2"
        ]
    },
    "dn": "cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap"
}
<class 'str'>

Dict形式で取得する

リーダーのentry_attributes_as_dictを使用することでLDAPの値をDict形式に変換して取得できる機能があります。

main.py

ldap_dict = data[0].entry_attributes_as_dict

print(ldap_dict)
print(type(ldap_dict))

結果


{'st': ['test2']}
<class 'dict'>

cnをパスにしてcnを1つ取得する

cnを指定することでその1つのcnのみ情報を取得することができます。

main.py

# cnをパスにすれば一個だけとれる
data_reader = Reader(conn, obj_cn_name, 'cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap')
data = data_reader.search()
print(data)

結果


[DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T21:16:17.284094
    cn: sample-name
    objectClass: inetOrgPerson
    sn: sample1
        sample2
    st: test2
]

Writerを使用したLDAPの書き込み

ldap3には色々な機能を持ったWriterクラスを使用してLDAPの情報を書き込むことができます。WriterにはReaderを利用して生成することができます。

Writerの生成・書き込み

Writerのfrom_cursor()にLDAPの値を取得したReaderを与えてWriterを生成します。
生成したWriterの変数に値を入れてcommit()することで値を書き込みます。

main.py

from ldap3 import Server, Connection, ObjectDef, Reader, Writer

server = Server('localhost')

conn = Connection(server, 'cn=admin,dc=sample-ldap',  password='LdapPass')
result = conn.bind()

# readerを使った取得
obj_cn_name = ObjectDef('inetOrgPerson', conn)
data_reader = Reader(conn, obj_cn_name, 'cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap')

data = data_reader.search()

# 更新前に表示する
print(data[0])

# writerに読み込ませる
data_writer = Writer.from_cursor(data_reader)

# writer経由で値を入れる
data_writer[0].sn = 'sample10'
data_writer[0].sn += 'sample20'
data_writer[0].st = 'test10'

# 変更結果の反映
data_writer.commit()

# 更新後に表示する
data_reader2 = Reader(conn, obj_cn_name, 'cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap')
data2 = data_reader2.search()
print(data2[0])

結果


DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T21:36:03.493031
    cn: sample-name
    objectClass: inetOrgPerson
    sn: sample1
        sample2
    st: test1

DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T21:36:03.686030
    cn: sample-name
    objectClass: inetOrgPerson
    sn: sample10
        sample20
    st: test10

指定したように値が変わっていることがわかります。

おわりに

LDAPのReaderとWriterを使用したLDAPの取得・変更・追加についてまとめました。ReaderとWriterを使用することでLDAPの扱い方が少し容易になった気がします。そのおかげでRDBの代わりにLDAPを使用するということが現実的になってきました。今回は極力簡単にするために構成を考えずにべたでソースを書いていきましたがもう少し工夫することでさらにソースが便利になるのではないかと思っています。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?