activeldap3 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (443) hide show
  1. data/.gitignore +6 -0
  2. data/CHANGES +691 -0
  3. data/COPYING +340 -0
  4. data/LICENSE +58 -0
  5. data/README +154 -0
  6. data/Rakefile +121 -0
  7. data/TODO +32 -0
  8. data/activeldap3.gemspec +18 -0
  9. data/benchmark/bench-al.rb +263 -0
  10. data/benchmark/config.yaml.sample +5 -0
  11. data/examples/al-admin/README +182 -0
  12. data/examples/al-admin/Rakefile +16 -0
  13. data/examples/al-admin/app/controllers/account_controller.rb +60 -0
  14. data/examples/al-admin/app/controllers/application_controller.rb +46 -0
  15. data/examples/al-admin/app/controllers/attributes_controller.rb +17 -0
  16. data/examples/al-admin/app/controllers/directory_controller.rb +49 -0
  17. data/examples/al-admin/app/controllers/object_classes_controller.rb +17 -0
  18. data/examples/al-admin/app/controllers/syntaxes_controller.rb +17 -0
  19. data/examples/al-admin/app/controllers/users_controller.rb +66 -0
  20. data/examples/al-admin/app/controllers/welcome_controller.rb +12 -0
  21. data/examples/al-admin/app/helpers/account_helper.rb +2 -0
  22. data/examples/al-admin/app/helpers/application_helper.rb +46 -0
  23. data/examples/al-admin/app/helpers/attributes_helper.rb +15 -0
  24. data/examples/al-admin/app/helpers/directory_helper.rb +7 -0
  25. data/examples/al-admin/app/helpers/object_classes_helper.rb +10 -0
  26. data/examples/al-admin/app/helpers/syntaxes_helper.rb +10 -0
  27. data/examples/al-admin/app/helpers/url_helper.rb +17 -0
  28. data/examples/al-admin/app/helpers/users_helper.rb +17 -0
  29. data/examples/al-admin/app/helpers/welcome_helper.rb +2 -0
  30. data/examples/al-admin/app/models/entry.rb +23 -0
  31. data/examples/al-admin/app/models/ldap_user.rb +58 -0
  32. data/examples/al-admin/app/models/user.rb +91 -0
  33. data/examples/al-admin/app/views/_entry/_attributes_information.html.erb +29 -0
  34. data/examples/al-admin/app/views/_entry/_entry.html.erb +15 -0
  35. data/examples/al-admin/app/views/_schema/_aliases.html.erb +7 -0
  36. data/examples/al-admin/app/views/_switcher/_after.html.erb +2 -0
  37. data/examples/al-admin/app/views/_switcher/_before.html.erb +5 -0
  38. data/examples/al-admin/app/views/account/login.html.erb +26 -0
  39. data/examples/al-admin/app/views/account/sign_up.html.erb +29 -0
  40. data/examples/al-admin/app/views/attributes/_attributes.html.erb +19 -0
  41. data/examples/al-admin/app/views/attributes/_detail.html.erb +29 -0
  42. data/examples/al-admin/app/views/attributes/index.html.erb +3 -0
  43. data/examples/al-admin/app/views/attributes/show.html.erb +31 -0
  44. data/examples/al-admin/app/views/directory/_tree.html.erb +10 -0
  45. data/examples/al-admin/app/views/directory/_tree_view_js.html.erb +25 -0
  46. data/examples/al-admin/app/views/directory/index.html.erb +13 -0
  47. data/examples/al-admin/app/views/directory/populate.html.erb +2 -0
  48. data/examples/al-admin/app/views/layouts/_footer.html.erb +11 -0
  49. data/examples/al-admin/app/views/layouts/_header_menu.html.erb +10 -0
  50. data/examples/al-admin/app/views/layouts/_main_menu.html.erb +18 -0
  51. data/examples/al-admin/app/views/layouts/application.html.erb +57 -0
  52. data/examples/al-admin/app/views/object_classes/_attributes.html.erb +28 -0
  53. data/examples/al-admin/app/views/object_classes/_object_classes.html.erb +19 -0
  54. data/examples/al-admin/app/views/object_classes/index.html.erb +3 -0
  55. data/examples/al-admin/app/views/object_classes/show.html.erb +39 -0
  56. data/examples/al-admin/app/views/syntaxes/_detail.html.erb +14 -0
  57. data/examples/al-admin/app/views/syntaxes/_syntaxes.html.erb +19 -0
  58. data/examples/al-admin/app/views/syntaxes/index.html.erb +3 -0
  59. data/examples/al-admin/app/views/syntaxes/show.html.erb +22 -0
  60. data/examples/al-admin/app/views/users/_attributes_update_form.html.erb +42 -0
  61. data/examples/al-admin/app/views/users/_form.html.erb +13 -0
  62. data/examples/al-admin/app/views/users/_object_classes_update_form.html.erb +46 -0
  63. data/examples/al-admin/app/views/users/_password_change_form.html.erb +20 -0
  64. data/examples/al-admin/app/views/users/edit.html.erb +15 -0
  65. data/examples/al-admin/app/views/users/index.html.erb +10 -0
  66. data/examples/al-admin/app/views/users/show.html.erb +11 -0
  67. data/examples/al-admin/app/views/welcome/index.html.erb +13 -0
  68. data/examples/al-admin/config.ru +7 -0
  69. data/examples/al-admin/config/boot.rb +110 -0
  70. data/examples/al-admin/config/database.yml.example +19 -0
  71. data/examples/al-admin/config/environment.rb +73 -0
  72. data/examples/al-admin/config/environments/development.rb +17 -0
  73. data/examples/al-admin/config/environments/production.rb +24 -0
  74. data/examples/al-admin/config/environments/test.rb +22 -0
  75. data/examples/al-admin/config/initializers/exception_notifier.rb +2 -0
  76. data/examples/al-admin/config/initializers/fast_gettext.rb +3 -0
  77. data/examples/al-admin/config/initializers/inflections.rb +10 -0
  78. data/examples/al-admin/config/initializers/mime_types.rb +5 -0
  79. data/examples/al-admin/config/initializers/session_store.rb +23 -0
  80. data/examples/al-admin/config/ldap.yml.example +21 -0
  81. data/examples/al-admin/config/routes.rb +58 -0
  82. data/examples/al-admin/db/migrate/001_create_users.rb +16 -0
  83. data/examples/al-admin/doc/README_FOR_APP +2 -0
  84. data/examples/al-admin/lib/authenticated_system.rb +124 -0
  85. data/examples/al-admin/lib/authenticated_test_helper.rb +113 -0
  86. data/examples/al-admin/lib/ldap_test_helper.rb +38 -0
  87. data/examples/al-admin/lib/tasks/testing.rake +10 -0
  88. data/examples/al-admin/po/en/al-admin.po +343 -0
  89. data/examples/al-admin/po/ja/al-admin.po +343 -0
  90. data/examples/al-admin/po/nl/al-admin.po +380 -0
  91. data/examples/al-admin/public/.htaccess +40 -0
  92. data/examples/al-admin/public/404.html +30 -0
  93. data/examples/al-admin/public/500.html +30 -0
  94. data/examples/al-admin/public/dispatch.cgi +10 -0
  95. data/examples/al-admin/public/dispatch.fcgi +24 -0
  96. data/examples/al-admin/public/dispatch.rb +10 -0
  97. data/examples/al-admin/public/favicon.ico +0 -0
  98. data/examples/al-admin/public/images/active-ldap.svg +6351 -0
  99. data/examples/al-admin/public/images/al-admin.png +0 -0
  100. data/examples/al-admin/public/images/al-admin.svg +6371 -0
  101. data/examples/al-admin/public/images/header-background.png +0 -0
  102. data/examples/al-admin/public/images/header-background.svg +99 -0
  103. data/examples/al-admin/public/images/rails.png +0 -0
  104. data/examples/al-admin/public/images/spinelz/accordion_tab_left_active.gif +0 -0
  105. data/examples/al-admin/public/images/spinelz/accordion_tab_left_inactive.gif +0 -0
  106. data/examples/al-admin/public/images/spinelz/accordion_tab_middle_active.gif +0 -0
  107. data/examples/al-admin/public/images/spinelz/accordion_tab_middle_inactive.gif +0 -0
  108. data/examples/al-admin/public/images/spinelz/accordion_tab_right_active.gif +0 -0
  109. data/examples/al-admin/public/images/spinelz/accordion_tab_right_inactive.gif +0 -0
  110. data/examples/al-admin/public/images/spinelz/balloon_back.gif +0 -0
  111. data/examples/al-admin/public/images/spinelz/balloon_bottom_left.gif +0 -0
  112. data/examples/al-admin/public/images/spinelz/balloon_bottom_middle.gif +0 -0
  113. data/examples/al-admin/public/images/spinelz/balloon_bottom_right.gif +0 -0
  114. data/examples/al-admin/public/images/spinelz/balloon_left_down_arrow.gif +0 -0
  115. data/examples/al-admin/public/images/spinelz/balloon_left_up_arrow.gif +0 -0
  116. data/examples/al-admin/public/images/spinelz/balloon_middle_left.gif +0 -0
  117. data/examples/al-admin/public/images/spinelz/balloon_middle_right.gif +0 -0
  118. data/examples/al-admin/public/images/spinelz/balloon_right_down_arrow.gif +0 -0
  119. data/examples/al-admin/public/images/spinelz/balloon_right_up_arrow.gif +0 -0
  120. data/examples/al-admin/public/images/spinelz/balloon_top_left.gif +0 -0
  121. data/examples/al-admin/public/images/spinelz/balloon_top_middle.gif +0 -0
  122. data/examples/al-admin/public/images/spinelz/balloon_top_right.gif +0 -0
  123. data/examples/al-admin/public/images/spinelz/barchart_h.gif +0 -0
  124. data/examples/al-admin/public/images/spinelz/barchart_v.gif +0 -0
  125. data/examples/al-admin/public/images/spinelz/button.gif +0 -0
  126. data/examples/al-admin/public/images/spinelz/calendar_default_handler.gif +0 -0
  127. data/examples/al-admin/public/images/spinelz/calendar_delete.gif +0 -0
  128. data/examples/al-admin/public/images/spinelz/calendar_next.gif +0 -0
  129. data/examples/al-admin/public/images/spinelz/calendar_next_second.gif +0 -0
  130. data/examples/al-admin/public/images/spinelz/calendar_pre.gif +0 -0
  131. data/examples/al-admin/public/images/spinelz/calendar_pre_second.gif +0 -0
  132. data/examples/al-admin/public/images/spinelz/calendar_private_icon.gif +0 -0
  133. data/examples/al-admin/public/images/spinelz/calendar_schedule.gif +0 -0
  134. data/examples/al-admin/public/images/spinelz/calender_back.gif +0 -0
  135. data/examples/al-admin/public/images/spinelz/calender_back_second.gif +0 -0
  136. data/examples/al-admin/public/images/spinelz/datepicker2_back.gif +0 -0
  137. data/examples/al-admin/public/images/spinelz/datepicker2_back_second.gif +0 -0
  138. data/examples/al-admin/public/images/spinelz/datepicker2_next.gif +0 -0
  139. data/examples/al-admin/public/images/spinelz/datepicker2_next_second.gif +0 -0
  140. data/examples/al-admin/public/images/spinelz/datepicker2_pre.gif +0 -0
  141. data/examples/al-admin/public/images/spinelz/datepicker2_pre_second.gif +0 -0
  142. data/examples/al-admin/public/images/spinelz/datepicker_back.gif +0 -0
  143. data/examples/al-admin/public/images/spinelz/datepicker_back_second.gif +0 -0
  144. data/examples/al-admin/public/images/spinelz/datepicker_next.gif +0 -0
  145. data/examples/al-admin/public/images/spinelz/datepicker_next_second.gif +0 -0
  146. data/examples/al-admin/public/images/spinelz/datepicker_pre.gif +0 -0
  147. data/examples/al-admin/public/images/spinelz/datepicker_pre_second.gif +0 -0
  148. data/examples/al-admin/public/images/spinelz/grid_down.gif +0 -0
  149. data/examples/al-admin/public/images/spinelz/grid_state.gif +0 -0
  150. data/examples/al-admin/public/images/spinelz/grid_up.gif +0 -0
  151. data/examples/al-admin/public/images/spinelz/icon_day.gif +0 -0
  152. data/examples/al-admin/public/images/spinelz/icon_month.gif +0 -0
  153. data/examples/al-admin/public/images/spinelz/icon_week.gif +0 -0
  154. data/examples/al-admin/public/images/spinelz/menubar_back.gif +0 -0
  155. data/examples/al-admin/public/images/spinelz/menubar_subcontents_back.gif +0 -0
  156. data/examples/al-admin/public/images/spinelz/navPanel_tab_left_active.gif +0 -0
  157. data/examples/al-admin/public/images/spinelz/navPanel_tab_left_inactive.gif +0 -0
  158. data/examples/al-admin/public/images/spinelz/navPanel_tab_middle_active.gif +0 -0
  159. data/examples/al-admin/public/images/spinelz/navPanel_tab_middle_inactive.gif +0 -0
  160. data/examples/al-admin/public/images/spinelz/navPanel_tab_right_active.gif +0 -0
  161. data/examples/al-admin/public/images/spinelz/navPanel_tab_right_inactive.gif +0 -0
  162. data/examples/al-admin/public/images/spinelz/select_date.gif +0 -0
  163. data/examples/al-admin/public/images/spinelz/selectabletable_selected.gif +0 -0
  164. data/examples/al-admin/public/images/spinelz/sideBarBox_about.gif +0 -0
  165. data/examples/al-admin/public/images/spinelz/sideBarBox_menu.gif +0 -0
  166. data/examples/al-admin/public/images/spinelz/sideBarBox_sample.gif +0 -0
  167. data/examples/al-admin/public/images/spinelz/sideBarBox_tabBottomActive.gif +0 -0
  168. data/examples/al-admin/public/images/spinelz/sideBarBox_tabBottomInactive.gif +0 -0
  169. data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleActive.gif +0 -0
  170. data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleActive2.gif +0 -0
  171. data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleInactive.gif +0 -0
  172. data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleInactive2.gif +0 -0
  173. data/examples/al-admin/public/images/spinelz/sideBarBox_tabTopActive.gif +0 -0
  174. data/examples/al-admin/public/images/spinelz/sideBarBox_tabTopInactive.gif +0 -0
  175. data/examples/al-admin/public/images/spinelz/sideBarBox_tabbar.gif +0 -0
  176. data/examples/al-admin/public/images/spinelz/sortableTable_down.gif +0 -0
  177. data/examples/al-admin/public/images/spinelz/sortableTable_normal.gif +0 -0
  178. data/examples/al-admin/public/images/spinelz/sortableTable_up.gif +0 -0
  179. data/examples/al-admin/public/images/spinelz/switcher_close.gif +0 -0
  180. data/examples/al-admin/public/images/spinelz/switcher_open.gif +0 -0
  181. data/examples/al-admin/public/images/spinelz/tabBox_close.gif +0 -0
  182. data/examples/al-admin/public/images/spinelz/tabBox_tabLeftActive.gif +0 -0
  183. data/examples/al-admin/public/images/spinelz/tabBox_tabLeftInactive.gif +0 -0
  184. data/examples/al-admin/public/images/spinelz/tabBox_tabMiddleActive.gif +0 -0
  185. data/examples/al-admin/public/images/spinelz/tabBox_tabMiddleInactive.gif +0 -0
  186. data/examples/al-admin/public/images/spinelz/tabBox_tabRightActive.gif +0 -0
  187. data/examples/al-admin/public/images/spinelz/tabBox_tabRightInactive.gif +0 -0
  188. data/examples/al-admin/public/images/spinelz/tab_bar.gif +0 -0
  189. data/examples/al-admin/public/images/spinelz/table_back.gif +0 -0
  190. data/examples/al-admin/public/images/spinelz/timepicker_clock.gif +0 -0
  191. data/examples/al-admin/public/images/spinelz/toolbar_close.gif +0 -0
  192. data/examples/al-admin/public/images/spinelz/toolbar_left.gif +0 -0
  193. data/examples/al-admin/public/images/spinelz/toolbar_max.gif +0 -0
  194. data/examples/al-admin/public/images/spinelz/toolbar_middle.gif +0 -0
  195. data/examples/al-admin/public/images/spinelz/toolbar_min.gif +0 -0
  196. data/examples/al-admin/public/images/spinelz/toolbar_next.gif +0 -0
  197. data/examples/al-admin/public/images/spinelz/toolbar_right.gif +0 -0
  198. data/examples/al-admin/public/images/spinelz/treeview_dir.gif +0 -0
  199. data/examples/al-admin/public/images/spinelz/treeview_file.gif +0 -0
  200. data/examples/al-admin/public/images/spinelz/treeview_group.gif +0 -0
  201. data/examples/al-admin/public/images/spinelz/treeview_group_special.gif +0 -0
  202. data/examples/al-admin/public/images/spinelz/treeview_state.gif +0 -0
  203. data/examples/al-admin/public/images/spinelz/treeview_user.gif +0 -0
  204. data/examples/al-admin/public/images/spinelz/window_bottom_left.gif +0 -0
  205. data/examples/al-admin/public/images/spinelz/window_bottom_middle.gif +0 -0
  206. data/examples/al-admin/public/images/spinelz/window_bottom_right.gif +0 -0
  207. data/examples/al-admin/public/images/spinelz/window_close.gif +0 -0
  208. data/examples/al-admin/public/images/spinelz/window_max.gif +0 -0
  209. data/examples/al-admin/public/images/spinelz/window_middle_left.gif +0 -0
  210. data/examples/al-admin/public/images/spinelz/window_middle_right.gif +0 -0
  211. data/examples/al-admin/public/images/spinelz/window_min.gif +0 -0
  212. data/examples/al-admin/public/images/spinelz/window_top_left.gif +0 -0
  213. data/examples/al-admin/public/images/spinelz/window_top_middle.gif +0 -0
  214. data/examples/al-admin/public/images/spinelz/window_top_right.gif +0 -0
  215. data/examples/al-admin/public/javascripts/application.js +2 -0
  216. data/examples/al-admin/public/javascripts/controls.js +963 -0
  217. data/examples/al-admin/public/javascripts/dragdrop.js +973 -0
  218. data/examples/al-admin/public/javascripts/effects.js +1128 -0
  219. data/examples/al-admin/public/javascripts/prototype.js +4320 -0
  220. data/examples/al-admin/public/javascripts/spinelz/accordion.js +185 -0
  221. data/examples/al-admin/public/javascripts/spinelz/ajaxHistory.js +157 -0
  222. data/examples/al-admin/public/javascripts/spinelz/balloon.js +287 -0
  223. data/examples/al-admin/public/javascripts/spinelz/barchart.js +524 -0
  224. data/examples/al-admin/public/javascripts/spinelz/calendar.js +3012 -0
  225. data/examples/al-admin/public/javascripts/spinelz/colorpicker.js +128 -0
  226. data/examples/al-admin/public/javascripts/spinelz/datepicker.js +438 -0
  227. data/examples/al-admin/public/javascripts/spinelz/grid.js +1391 -0
  228. data/examples/al-admin/public/javascripts/spinelz/grid_resizeEx.js +100 -0
  229. data/examples/al-admin/public/javascripts/spinelz/grid_sortabletableEx.js +129 -0
  230. data/examples/al-admin/public/javascripts/spinelz/inplaceEditorEx.js +148 -0
  231. data/examples/al-admin/public/javascripts/spinelz/menubar.js +232 -0
  232. data/examples/al-admin/public/javascripts/spinelz/navPanel.js +170 -0
  233. data/examples/al-admin/public/javascripts/spinelz/selectableTable.js +433 -0
  234. data/examples/al-admin/public/javascripts/spinelz/sideBarBox.js +282 -0
  235. data/examples/al-admin/public/javascripts/spinelz/sideBarBox_effects.js +83 -0
  236. data/examples/al-admin/public/javascripts/spinelz/sortableTable.js +270 -0
  237. data/examples/al-admin/public/javascripts/spinelz/switcher.js +78 -0
  238. data/examples/al-admin/public/javascripts/spinelz/tabBox.js +469 -0
  239. data/examples/al-admin/public/javascripts/spinelz/timepicker.js +384 -0
  240. data/examples/al-admin/public/javascripts/spinelz/toolbar.js +152 -0
  241. data/examples/al-admin/public/javascripts/spinelz/treeview.js +703 -0
  242. data/examples/al-admin/public/javascripts/spinelz/window.js +641 -0
  243. data/examples/al-admin/public/javascripts/spinelz/window_resizeEx.js +130 -0
  244. data/examples/al-admin/public/javascripts/spinelz_lib/builder.js +131 -0
  245. data/examples/al-admin/public/javascripts/spinelz_lib/controls.js +835 -0
  246. data/examples/al-admin/public/javascripts/spinelz_lib/dragdrop.js +944 -0
  247. data/examples/al-admin/public/javascripts/spinelz_lib/effects.js +1090 -0
  248. data/examples/al-admin/public/javascripts/spinelz_lib/json.js +139 -0
  249. data/examples/al-admin/public/javascripts/spinelz_lib/prototype.js +2515 -0
  250. data/examples/al-admin/public/javascripts/spinelz_lib/resize.js +215 -0
  251. data/examples/al-admin/public/javascripts/spinelz_lib/scriptaculous.js +51 -0
  252. data/examples/al-admin/public/javascripts/spinelz_lib/slider.js +278 -0
  253. data/examples/al-admin/public/javascripts/spinelz_lib/spinelz_util.js +1266 -0
  254. data/examples/al-admin/public/javascripts/spinelz_lib/unittest.js +564 -0
  255. data/examples/al-admin/public/robots.txt +1 -0
  256. data/examples/al-admin/public/stylesheets/account.css +41 -0
  257. data/examples/al-admin/public/stylesheets/attributes.css +1 -0
  258. data/examples/al-admin/public/stylesheets/base.css +104 -0
  259. data/examples/al-admin/public/stylesheets/detail.css +36 -0
  260. data/examples/al-admin/public/stylesheets/directory.css +22 -0
  261. data/examples/al-admin/public/stylesheets/object-classes.css +6 -0
  262. data/examples/al-admin/public/stylesheets/rails.css +35 -0
  263. data/examples/al-admin/public/stylesheets/spinelz/accordion.css +59 -0
  264. data/examples/al-admin/public/stylesheets/spinelz/balloon.css +151 -0
  265. data/examples/al-admin/public/stylesheets/spinelz/calendar.css +564 -0
  266. data/examples/al-admin/public/stylesheets/spinelz/datepicker.css +175 -0
  267. data/examples/al-admin/public/stylesheets/spinelz/grid.css +137 -0
  268. data/examples/al-admin/public/stylesheets/spinelz/menubar.css +78 -0
  269. data/examples/al-admin/public/stylesheets/spinelz/modal.css +22 -0
  270. data/examples/al-admin/public/stylesheets/spinelz/navPanel.css +58 -0
  271. data/examples/al-admin/public/stylesheets/spinelz/selectableTable.css +28 -0
  272. data/examples/al-admin/public/stylesheets/spinelz/sideBarBox.css +82 -0
  273. data/examples/al-admin/public/stylesheets/spinelz/sortableTable.css +51 -0
  274. data/examples/al-admin/public/stylesheets/spinelz/switcher.css +23 -0
  275. data/examples/al-admin/public/stylesheets/spinelz/tabBox.css +94 -0
  276. data/examples/al-admin/public/stylesheets/spinelz/timepicker.css +508 -0
  277. data/examples/al-admin/public/stylesheets/spinelz/toolbar.css +82 -0
  278. data/examples/al-admin/public/stylesheets/spinelz/treeview.css +121 -0
  279. data/examples/al-admin/public/stylesheets/spinelz/window.css +140 -0
  280. data/examples/al-admin/public/stylesheets/structure.css +81 -0
  281. data/examples/al-admin/public/stylesheets/syntaxes.css +1 -0
  282. data/examples/al-admin/public/stylesheets/users.css +13 -0
  283. data/examples/al-admin/public/stylesheets/welcome.css +0 -0
  284. data/examples/al-admin/script/about +3 -0
  285. data/examples/al-admin/script/console +3 -0
  286. data/examples/al-admin/script/dbconsole +3 -0
  287. data/examples/al-admin/script/destroy +3 -0
  288. data/examples/al-admin/script/generate +3 -0
  289. data/examples/al-admin/script/performance/benchmarker +3 -0
  290. data/examples/al-admin/script/performance/profiler +3 -0
  291. data/examples/al-admin/script/performance/request +3 -0
  292. data/examples/al-admin/script/plugin +3 -0
  293. data/examples/al-admin/script/process/inspector +3 -0
  294. data/examples/al-admin/script/process/reaper +3 -0
  295. data/examples/al-admin/script/process/spawner +3 -0
  296. data/examples/al-admin/script/runner +3 -0
  297. data/examples/al-admin/script/server +3 -0
  298. data/examples/al-admin/test/fixtures/users.yml +9 -0
  299. data/examples/al-admin/test/functional/account_controller_test.rb +12 -0
  300. data/examples/al-admin/test/functional/attributes_controller_test.rb +8 -0
  301. data/examples/al-admin/test/functional/directory_controller_test.rb +8 -0
  302. data/examples/al-admin/test/functional/object_classes_controller_test.rb +8 -0
  303. data/examples/al-admin/test/functional/syntaxes_controller_test.rb +8 -0
  304. data/examples/al-admin/test/functional/users_controller_test.rb +8 -0
  305. data/examples/al-admin/test/functional/welcome_controller_test.rb +8 -0
  306. data/examples/al-admin/test/integration/sign_up_test.rb +44 -0
  307. data/examples/al-admin/test/run-test.sh +3 -0
  308. data/examples/al-admin/test/test_helper.rb +52 -0
  309. data/examples/al-admin/test/unit/user_test.rb +12 -0
  310. data/examples/al-admin/vendor/plugins/exception_notification/README +111 -0
  311. data/examples/al-admin/vendor/plugins/exception_notification/init.rb +1 -0
  312. data/examples/al-admin/vendor/plugins/exception_notification/lib/exception_notifiable.rb +99 -0
  313. data/examples/al-admin/vendor/plugins/exception_notification/lib/exception_notifier.rb +66 -0
  314. data/examples/al-admin/vendor/plugins/exception_notification/lib/exception_notifier_helper.rb +78 -0
  315. data/examples/al-admin/vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb +61 -0
  316. data/examples/al-admin/vendor/plugins/exception_notification/test/test_helper.rb +7 -0
  317. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml +1 -0
  318. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml +7 -0
  319. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml +16 -0
  320. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml +4 -0
  321. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml +2 -0
  322. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml +3 -0
  323. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml +6 -0
  324. data/examples/config.yaml.example +5 -0
  325. data/examples/example.der +0 -0
  326. data/examples/example.jpg +0 -0
  327. data/examples/groupadd +41 -0
  328. data/examples/groupdel +35 -0
  329. data/examples/groupls +49 -0
  330. data/examples/groupmod +42 -0
  331. data/examples/lpasswd +55 -0
  332. data/examples/objects/group.rb +13 -0
  333. data/examples/objects/ou.rb +4 -0
  334. data/examples/objects/user.rb +20 -0
  335. data/examples/ouadd +38 -0
  336. data/examples/useradd +45 -0
  337. data/examples/useradd-binary +53 -0
  338. data/examples/userdel +34 -0
  339. data/examples/userls +50 -0
  340. data/examples/usermod +42 -0
  341. data/examples/usermod-binary-add +50 -0
  342. data/examples/usermod-binary-add-time +54 -0
  343. data/examples/usermod-binary-del +48 -0
  344. data/examples/usermod-lang-add +43 -0
  345. data/lib/active_ldap.rb +105 -0
  346. data/lib/active_ldap/action_controller/ldap_benchmarking.rb +55 -0
  347. data/lib/active_ldap/acts/tree.rb +75 -0
  348. data/lib/active_ldap/adapter/base.rb +705 -0
  349. data/lib/active_ldap/adapter/jndi.rb +184 -0
  350. data/lib/active_ldap/adapter/jndi_connection.rb +185 -0
  351. data/lib/active_ldap/adapter/ldap.rb +290 -0
  352. data/lib/active_ldap/adapter/ldap_ext.rb +105 -0
  353. data/lib/active_ldap/adapter/net_ldap.rb +309 -0
  354. data/lib/active_ldap/adapter/net_ldap_ext.rb +23 -0
  355. data/lib/active_ldap/association/belongs_to.rb +47 -0
  356. data/lib/active_ldap/association/belongs_to_many.rb +58 -0
  357. data/lib/active_ldap/association/children.rb +21 -0
  358. data/lib/active_ldap/association/collection.rb +105 -0
  359. data/lib/active_ldap/association/has_many.rb +31 -0
  360. data/lib/active_ldap/association/has_many_utils.rb +44 -0
  361. data/lib/active_ldap/association/has_many_wrap.rb +62 -0
  362. data/lib/active_ldap/association/proxy.rb +107 -0
  363. data/lib/active_ldap/associations.rb +202 -0
  364. data/lib/active_ldap/attributes.rb +184 -0
  365. data/lib/active_ldap/base.rb +1594 -0
  366. data/lib/active_ldap/callbacks.rb +52 -0
  367. data/lib/active_ldap/command.rb +49 -0
  368. data/lib/active_ldap/compatible.rb +44 -0
  369. data/lib/active_ldap/configuration.rb +147 -0
  370. data/lib/active_ldap/connection.rb +294 -0
  371. data/lib/active_ldap/distinguished_name.rb +291 -0
  372. data/lib/active_ldap/entry_attribute.rb +78 -0
  373. data/lib/active_ldap/escape.rb +12 -0
  374. data/lib/active_ldap/get_text.rb +9 -0
  375. data/lib/active_ldap/get_text/parser.rb +161 -0
  376. data/lib/active_ldap/get_text_fallback.rb +60 -0
  377. data/lib/active_ldap/get_text_support.rb +20 -0
  378. data/lib/active_ldap/helper.rb +92 -0
  379. data/lib/active_ldap/human_readable.rb +132 -0
  380. data/lib/active_ldap/ldap_error.rb +74 -0
  381. data/lib/active_ldap/ldif.rb +930 -0
  382. data/lib/active_ldap/object_class.rb +95 -0
  383. data/lib/active_ldap/operations.rb +610 -0
  384. data/lib/active_ldap/populate.rb +53 -0
  385. data/lib/active_ldap/railtie.rb +31 -0
  386. data/lib/active_ldap/schema.rb +699 -0
  387. data/lib/active_ldap/schema/syntaxes.rb +417 -0
  388. data/lib/active_ldap/timeout.rb +75 -0
  389. data/lib/active_ldap/timeout_stub.rb +17 -0
  390. data/lib/active_ldap/user_password.rb +92 -0
  391. data/lib/active_ldap/validations.rb +229 -0
  392. data/lib/active_ldap/xml.rb +122 -0
  393. data/po/en/active-ldap.po +4029 -0
  394. data/po/ja/active-ldap.po +4060 -0
  395. data/rails_generators/model_active_ldap/USAGE +17 -0
  396. data/rails_generators/model_active_ldap/model_active_ldap_generator.rb +69 -0
  397. data/rails_generators/model_active_ldap/templates/model_active_ldap.rb +3 -0
  398. data/rails_generators/model_active_ldap/templates/unit_test.rb +8 -0
  399. data/rails_generators/scaffold_active_ldap/scaffold_active_ldap_generator.rb +7 -0
  400. data/rails_generators/scaffold_active_ldap/templates/ldap.yml +18 -0
  401. data/test/al-test-utils.rb +439 -0
  402. data/test/command.rb +112 -0
  403. data/test/config.yaml.sample +6 -0
  404. data/test/fixtures/lower_case_object_class_schema.rb +802 -0
  405. data/test/run-test.rb +44 -0
  406. data/test/test_acts_as_tree.rb +60 -0
  407. data/test/test_adapter.rb +121 -0
  408. data/test/test_associations.rb +664 -0
  409. data/test/test_attributes.rb +117 -0
  410. data/test/test_base.rb +1177 -0
  411. data/test/test_base_per_instance.rb +61 -0
  412. data/test/test_bind.rb +62 -0
  413. data/test/test_callback.rb +37 -0
  414. data/test/test_configuration.rb +40 -0
  415. data/test/test_connection.rb +82 -0
  416. data/test/test_connection_per_class.rb +112 -0
  417. data/test/test_connection_per_dn.rb +112 -0
  418. data/test/test_dn.rb +172 -0
  419. data/test/test_find.rb +176 -0
  420. data/test/test_groupadd.rb +50 -0
  421. data/test/test_groupdel.rb +46 -0
  422. data/test/test_groupls.rb +107 -0
  423. data/test/test_groupmod.rb +51 -0
  424. data/test/test_ldif.rb +1891 -0
  425. data/test/test_load.rb +133 -0
  426. data/test/test_lpasswd.rb +75 -0
  427. data/test/test_object_class.rb +74 -0
  428. data/test/test_reflection.rb +182 -0
  429. data/test/test_schema.rb +559 -0
  430. data/test/test_syntax.rb +383 -0
  431. data/test/test_user.rb +217 -0
  432. data/test/test_user_password.rb +101 -0
  433. data/test/test_useradd-binary.rb +62 -0
  434. data/test/test_useradd.rb +57 -0
  435. data/test/test_userdel.rb +48 -0
  436. data/test/test_userls.rb +91 -0
  437. data/test/test_usermod-binary-add-time.rb +65 -0
  438. data/test/test_usermod-binary-add.rb +64 -0
  439. data/test/test_usermod-binary-del.rb +66 -0
  440. data/test/test_usermod-lang-add.rb +60 -0
  441. data/test/test_usermod.rb +58 -0
  442. data/test/test_validation.rb +274 -0
  443. metadata +502 -0
@@ -0,0 +1,184 @@
1
+ require 'active_ldap/adapter/base'
2
+
3
+ module ActiveLdap
4
+ module Adapter
5
+ class Base
6
+ class << self
7
+ def jndi_connection(options)
8
+ require 'active_ldap/adapter/jndi_connection'
9
+ Jndi.new(options)
10
+ end
11
+ end
12
+ end
13
+
14
+ class Jndi < Base
15
+ METHOD = {
16
+ :ssl => :ssl,
17
+ :tls => :start_tls,
18
+ :plain => nil,
19
+ }
20
+
21
+ def connect(options={})
22
+ super do |host, port, method|
23
+ uri = construct_uri(host, port, method == :ssl)
24
+ with_start_tls = method == :start_tls
25
+ info = {:uri => uri, :with_start_tls => with_start_tls}
26
+ [log("connect", info) {JndiConnection.new(host, port, method)},
27
+ uri, with_start_tls]
28
+ end
29
+ end
30
+
31
+ def unbind(options={})
32
+ super do
33
+ execute(:unbind)
34
+ end
35
+ end
36
+
37
+ def bind_as_anonymous(options={})
38
+ super do
39
+ execute(:bind_as_anonymous, :name => "bind: anonymous")
40
+ true
41
+ end
42
+ end
43
+
44
+ def search(options={}, &block)
45
+ super(options) do |base, scope, filter, attrs, limit|
46
+ info = {
47
+ :base => base, :scope => scope_name(scope), :filter => filter,
48
+ :attributes => attrs, :limit => limit,
49
+ }
50
+ execute(:search, info, base, scope, filter, attrs, limit, &block)
51
+ end
52
+ end
53
+
54
+ def delete(targets, options={})
55
+ super do |target|
56
+ execute(:delete, {:dn => target}, target)
57
+ end
58
+ end
59
+
60
+ def add(dn, entries, options={})
61
+ super do |_dn, _entries|
62
+ info = {:dn => _dn, :attributes => _entries}
63
+ execute(:add, info, _dn, parse_entries(_entries))
64
+ end
65
+ end
66
+
67
+ def modify(dn, entries, options={})
68
+ super do |_dn, _entries|
69
+ info = {:dn => _dn, :attributes => _entries}
70
+ execute(:modify, info, _dn, parse_entries(_entries))
71
+ end
72
+ end
73
+
74
+ def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={})
75
+ super do |_dn, _new_rdn, _delete_old_rdn, _new_superior|
76
+ info = {
77
+ :name => "modify: RDN",
78
+ :dn => _dn,
79
+ :new_rdn => _new_rdn,
80
+ :new_superior => _new_superior,
81
+ :delete_old_rdn => _delete_old_rdn
82
+ }
83
+ _new_rdn = "#{_new_rdn},#{_new_superior}" if _new_superior
84
+ execute(:modify_rdn, info, _dn, _new_rdn, _delete_old_rdn)
85
+ end
86
+ end
87
+
88
+ private
89
+ def execute(method, info=nil, *args, &block)
90
+ name = (info || {}).delete(:name) || method
91
+ log(name, info) {@connection.send(method, *args, &block)}
92
+ rescue JndiConnection::NamingException
93
+ if /\[LDAP: error code (\d+) - ([^\]]+)\]/ =~ $!.to_s
94
+ message = $2
95
+ klass = LdapError::ERRORS[Integer($1)]
96
+ klass ||= ActiveLdap::LdapError
97
+ raise klass, message
98
+ end
99
+ raise
100
+ end
101
+
102
+ def ensure_method(method)
103
+ method ||= "plain"
104
+ normalized_method = method.to_s.downcase.to_sym
105
+ return METHOD[normalized_method] if METHOD.has_key?(normalized_method)
106
+
107
+ available_methods = METHOD.keys.collect {|m| m.inspect}.join(", ")
108
+ format = _("%s is not one of the available connect methods: %s")
109
+ raise ConfigurationError, format % [method.inspect, available_methods]
110
+ end
111
+
112
+ def ensure_scope(scope)
113
+ scope_map = {
114
+ :base => JndiConnection::Scope::OBJECT,
115
+ :one => JndiConnection::Scope::ONE_LEVEL,
116
+ :sub => JndiConnection::Scope::SUBTREE,
117
+ }
118
+ value = scope_map[scope || :sub]
119
+ if value.nil?
120
+ available_scopes = scope_map.keys.inspect
121
+ format = _("%s is not one of the available LDAP scope: %s")
122
+ raise ArgumentError, format % [scope.inspect, available_scopes]
123
+ end
124
+ value
125
+ end
126
+
127
+ def scope_name(scope)
128
+ {
129
+ JndiConnection::Scope::OBJECT => :base,
130
+ JndiConnection::Scope::ONE_LEVEL => :one,
131
+ JndiConnection::Scope::SUBTREE => :sub,
132
+ }[scope]
133
+ end
134
+
135
+ def sasl_bind(bind_dn, options={})
136
+ super do |_bind_dn, mechanism, quiet|
137
+ info = {
138
+ :name => "bind: SASL",
139
+ :dn => _bind_dn,
140
+ :mechanism => mechanism
141
+ }
142
+ execute(:sasl_bind, info, _bind_dn, mechanism, quiet)
143
+ true
144
+ end
145
+ end
146
+
147
+ def simple_bind(bind_dn, options={})
148
+ super do |_bind_dn, password|
149
+ info = {:name => "bind", :dn => _bind_dn}
150
+ execute(:simple_bind, info, _bind_dn, password)
151
+ true
152
+ end
153
+ end
154
+
155
+ def parse_entries(entries)
156
+ result = []
157
+ entries.each do |type, key, attributes|
158
+ mod_type = ensure_mod_type(type)
159
+ binary = schema.attribute(key).binary?
160
+ attributes.each do |name, values|
161
+ real_binary = binary
162
+ if values.any? {|value| Ldif::Attribute.binary_value?(value)}
163
+ real_binary = true
164
+ end
165
+ result << JndiConnection::ModifyRecord.new(mod_type, name,
166
+ values, real_binary)
167
+ end
168
+ end
169
+ result
170
+ end
171
+
172
+ def ensure_mod_type(type)
173
+ case type
174
+ when :replace, :add
175
+ type
176
+ when :delete
177
+ :remove
178
+ else
179
+ raise ArgumentError, _("unknown type: %s") % type
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,185 @@
1
+ require 'java'
2
+
3
+ java.util.Enumeration.module_eval do
4
+ include Enumerable
5
+
6
+ def each
7
+ while has_more_elements
8
+ yield(next_element)
9
+ end
10
+ end
11
+ end
12
+
13
+ module ActiveLdap
14
+ module Adapter
15
+ class JndiConnection
16
+ HashTable = java.util.Hashtable
17
+ naming = javax.naming
18
+ directory = naming.directory
19
+ ldap = naming.ldap
20
+ InitialDirContext = directory.InitialDirContext
21
+ InitialLdapContext = ldap.InitialLdapContext
22
+ SearchControls = directory.SearchControls
23
+ ModificationItem = directory.ModificationItem
24
+ BasicAttributes = directory.BasicAttributes
25
+ Context = naming.Context
26
+ StartTlsRequest = ldap.StartTlsRequest
27
+ Control = ldap.Control
28
+
29
+ NamingException = naming.NamingException
30
+ NameNotFoundException = naming.NameNotFoundException
31
+
32
+ module Scope
33
+ OBJECT = SearchControls::OBJECT_SCOPE
34
+ ONE_LEVEL = SearchControls::ONELEVEL_SCOPE
35
+ SUBTREE = SearchControls::SUBTREE_SCOPE
36
+ end
37
+
38
+ class ModifyRecord
39
+ directory = javax.naming.directory
40
+ DirContext = directory.DirContext
41
+ BasicAttribute = directory.BasicAttribute
42
+
43
+ ADD_ATTRIBUTE = DirContext::ADD_ATTRIBUTE
44
+ REPLACE_ATTRIBUTE = DirContext::REPLACE_ATTRIBUTE
45
+ REMOVE_ATTRIBUTE = DirContext::REMOVE_ATTRIBUTE
46
+
47
+ attr_reader :type, :name, :values
48
+ def initialize(type, name, values, binary)
49
+ @type = self.class.const_get("#{type.to_s.upcase}_ATTRIBUTE")
50
+ @name = name
51
+ @values = values
52
+ @binary = binary
53
+ end
54
+
55
+ def binary?
56
+ @binary
57
+ end
58
+
59
+ def to_java_modification_item
60
+ ModificationItem.new(@type, to_java_attribute)
61
+ end
62
+
63
+ def to_java_attribute
64
+ attribute = BasicAttribute.new(@name)
65
+ values = @values
66
+ values = values.collect(&:to_java_bytes) if binary?
67
+ values.each do |value|
68
+ attribute.add(value)
69
+ end
70
+ attribute
71
+ end
72
+ end
73
+
74
+ def initialize(host, port, method)
75
+ @host = host
76
+ @port = port
77
+ @method = method
78
+ @context = nil
79
+ @tls = nil
80
+ end
81
+
82
+ def unbind
83
+ @tls.close if @tls
84
+ @tls = nil
85
+ @context.close if @context
86
+ @context = nil
87
+ end
88
+
89
+ def bound?
90
+ not @context.nil?
91
+ end
92
+
93
+ def sasl_bind(bind_dn, mechanism, quiet)
94
+ setup_context(bind_dn, password, mechanism)
95
+ bound?
96
+ end
97
+
98
+ def simple_bind(bind_dn, password)
99
+ setup_context(bind_dn, password, "simple")
100
+ bound?
101
+ end
102
+
103
+ def bind_as_anonymous
104
+ setup_context(nil, nil, "none")
105
+ bound?
106
+ end
107
+
108
+ def search(base, scope, filter, attrs, limit)
109
+ controls = SearchControls.new
110
+ controls.search_scope = scope
111
+
112
+ controls.count_limit = limit if limit
113
+ unless attrs.blank?
114
+ controls.returning_attributes = attrs.to_java(:string)
115
+ end
116
+
117
+ @context.search(base, filter, controls).each do |result|
118
+ attributes = {}
119
+ result.attributes.get_all.each do |attribute|
120
+ attributes[attribute.get_id] = attribute.get_all.collect do |value|
121
+ value.is_a?(String) ? value : String.from_java_bytes(value)
122
+ end
123
+ end
124
+ yield([result.name_in_namespace, attributes])
125
+ end
126
+ end
127
+
128
+ def add(dn, records)
129
+ attributes = BasicAttributes.new
130
+ records.each do |record|
131
+ attributes.put(record.to_java_attribute)
132
+ end
133
+ @context.create_subcontext(dn, attributes)
134
+ end
135
+
136
+ def modify(dn, records)
137
+ items = records.collect(&:to_java_modification_item)
138
+ @context.modify_attributes(dn, items.to_java(ModificationItem))
139
+ end
140
+
141
+ def modify_rdn(dn, new_rdn, delete_old_rdn)
142
+ # should use mutex
143
+ delete_rdn_key = "java.naming.ldap.deleteRDN"
144
+ @context.add_to_environment(delete_rdn_key, delete_old_rdn.to_s)
145
+ @context.rename(dn, new_rdn)
146
+ ensure
147
+ @context.remove_from_environment(delete_rdn_key)
148
+ end
149
+
150
+ def delete(dn)
151
+ @context.destroy_subcontext(dn)
152
+ end
153
+
154
+ private
155
+ def setup_context(bind_dn, password, authentication)
156
+ unbind
157
+ environment = {
158
+ Context::INITIAL_CONTEXT_FACTORY => "com.sun.jndi.ldap.LdapCtxFactory",
159
+ Context::PROVIDER_URL => ldap_uri,
160
+ }
161
+ environment = HashTable.new(environment)
162
+ context = InitialLdapContext.new(environment, nil)
163
+ if @method == :start_tls
164
+ @tls = context.extended_operation(StartTlsRequest.new)
165
+ @tls.negotiate
166
+ end
167
+ context.add_to_environment(Context::SECURITY_AUTHENTICATION,
168
+ authentication)
169
+ if bind_dn
170
+ context.add_to_environment(Context::SECURITY_PRINCIPAL, bind_dn)
171
+ end
172
+ if password
173
+ context.add_to_environment(Context::SECURITY_CREDENTIALS, password)
174
+ end
175
+ context.reconnect(nil)
176
+ @context = context
177
+ end
178
+
179
+ def ldap_uri
180
+ protocol = @method == :ssl ? "ldaps" : "ldap"
181
+ "#{protocol}://#{@host}:#{@port}/"
182
+ end
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,290 @@
1
+ require 'active_ldap/adapter/base'
2
+
3
+ module ActiveLdap
4
+ module Adapter
5
+ class Base
6
+ class << self
7
+ def ldap_connection(options)
8
+ require 'active_ldap/adapter/ldap_ext'
9
+ Ldap.new(options)
10
+ end
11
+ end
12
+ end
13
+
14
+ class Ldap < Base
15
+ module Method
16
+ class Base
17
+ def ssl?
18
+ false
19
+ end
20
+
21
+ def start_tls?
22
+ false
23
+ end
24
+ end
25
+
26
+ class SSL < Base
27
+ def connect(host, port)
28
+ LDAP::SSLConn.new(host, port, false)
29
+ end
30
+
31
+ def ssl?
32
+ true
33
+ end
34
+ end
35
+
36
+ class TLS < Base
37
+ def connect(host, port)
38
+ LDAP::SSLConn.new(host, port, true)
39
+ end
40
+
41
+ def start_tls?
42
+ true
43
+ end
44
+ end
45
+
46
+ class Plain < Base
47
+ def connect(host, port)
48
+ LDAP::Conn.new(host, port)
49
+ end
50
+ end
51
+ end
52
+
53
+ def connect(options={})
54
+ super do |host, port, method|
55
+ uri = construct_uri(host, port, method.ssl?)
56
+ with_start_tls = method.start_tls?
57
+ info = {:uri => uri, :with_start_tls => with_start_tls}
58
+ [log("connect", info) {method.connect(host, port)},
59
+ uri, with_start_tls]
60
+ end
61
+ end
62
+
63
+ def unbind(options={})
64
+ super do
65
+ execute(:unbind)
66
+ end
67
+ end
68
+
69
+ def bind(options={})
70
+ super do
71
+ @connection.error_message
72
+ end
73
+ end
74
+
75
+ def bind_as_anonymous(options={})
76
+ super do
77
+ execute(:bind, :name => "bind: anonymous")
78
+ true
79
+ end
80
+ end
81
+
82
+ def search(options={})
83
+ super(options) do |base, scope, filter, attrs, limit|
84
+ begin
85
+ info = {
86
+ :base => base, :scope => scope_name(scope),
87
+ :filter => filter, :attributes => attrs, :limit => limit,
88
+ }
89
+ execute(:search_with_limit,
90
+ info, base, scope, filter, attrs, limit) do |entry|
91
+ attributes = {}
92
+ entry.attrs.each do |attr|
93
+ value = entry.vals(attr)
94
+ attributes[attr] = value if value
95
+ end
96
+ yield([entry.dn, attributes])
97
+ end
98
+ rescue RuntimeError
99
+ if $!.message == "no result returned by search"
100
+ @logger.debug do
101
+ args = [filter, attrs.inspect]
102
+ _("No matches: filter: %s: attributes: %s") % args
103
+ end
104
+ else
105
+ raise
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ def delete(targets, options={})
112
+ super do |target|
113
+ controls = options[:controls]
114
+ info = {:dn => target}
115
+ if controls
116
+ info.merge!(:name => :delete, :controls => controls)
117
+ execute(:delete_ext, info,
118
+ target, controls, [])
119
+ else
120
+ execute(:delete, info, target)
121
+ end
122
+ end
123
+ end
124
+
125
+ def add(dn, entries, options={})
126
+ super do |_dn, _entries|
127
+ controls = options[:controls]
128
+ attributes = parse_entries(_entries)
129
+ info = {:dn => _dn, :attributes => _entries}
130
+ if controls
131
+ info.merge!(:name => :add, :controls => controls)
132
+ execute(:add_ext, info, _dn, attributes, controls, [])
133
+ else
134
+ execute(:add, info, _dn, attributes)
135
+ end
136
+ end
137
+ end
138
+
139
+ def modify(dn, entries, options={})
140
+ super do |_dn, _entries|
141
+ controls = options[:controls]
142
+ attributes = parse_entries(_entries)
143
+ info = {:dn => _dn, :attributes => _entries}
144
+ if controls
145
+ info.merge!(:name => :modify, :controls => controls)
146
+ execute(:modify_ext, info, _dn, attributes, controls, [])
147
+ else
148
+ execute(:modify, info, _dn, attributes)
149
+ end
150
+ end
151
+ end
152
+
153
+ def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={})
154
+ super do |_dn, _new_rdn, _delete_old_rdn, _new_superior|
155
+ if _new_superior
156
+ raise NotImplemented.new(_("modify RDN with new superior"))
157
+ end
158
+ info = {
159
+ :name => "modify: RDN",
160
+ :dn => _dn,
161
+ :new_rdn => _new_rdn,
162
+ :new_superior => _new_superior,
163
+ :delete_old_rdn => _delete_old_rdn
164
+ }
165
+ execute(:modrdn, info, _dn, _new_rdn, _delete_old_rdn)
166
+ end
167
+ end
168
+
169
+ private
170
+ def prepare_connection(options={})
171
+ operation(options) do
172
+ @connection.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
173
+ end
174
+ end
175
+
176
+ def execute(method, info=nil, *args, &block)
177
+ begin
178
+ name = (info || {}).delete(:name) || method
179
+ log(name, info) {@connection.send(method, *args, &block)}
180
+ rescue LDAP::ResultError
181
+ @connection.assert_error_code
182
+ raise $!.message
183
+ end
184
+ end
185
+
186
+ def do_in_timeout(timeout, &block)
187
+ Timeout.timeout(timeout, &block)
188
+ end
189
+
190
+ def ensure_method(method)
191
+ normalized_method = method.to_s.downcase
192
+ Method.constants.each do |name|
193
+ if normalized_method == name.to_s.downcase
194
+ return Method.const_get(name).new
195
+ end
196
+ end
197
+
198
+ available_methods = Method.constants.collect do |name|
199
+ name.downcase.to_sym.inspect
200
+ end.join(", ")
201
+ format = _("%s is not one of the available connect methods: %s")
202
+ raise ConfigurationError, format % [method.inspect, available_methods]
203
+ end
204
+
205
+ def ensure_scope(scope)
206
+ scope_map = {
207
+ :base => LDAP::LDAP_SCOPE_BASE,
208
+ :sub => LDAP::LDAP_SCOPE_SUBTREE,
209
+ :one => LDAP::LDAP_SCOPE_ONELEVEL,
210
+ }
211
+ value = scope_map[scope || :sub]
212
+ if value.nil?
213
+ available_scopes = scope_map.keys.inspect
214
+ format = _("%s is not one of the available LDAP scope: %s")
215
+ raise ArgumentError, format % [scope.inspect, available_scopes]
216
+ end
217
+ value
218
+ end
219
+
220
+ def scope_name(scope)
221
+ {
222
+ LDAP::LDAP_SCOPE_BASE => :base,
223
+ LDAP::LDAP_SCOPE_SUBTREE => :sub,
224
+ LDAP::LDAP_SCOPE_ONELEVEL => :one,
225
+ }[scope]
226
+ end
227
+
228
+ def sasl_bind(bind_dn, options={})
229
+ super do |_bind_dn, mechanism, quiet|
230
+ begin
231
+ _bind_dn ||= ''
232
+ sasl_quiet = @connection.sasl_quiet
233
+ @connection.sasl_quiet = quiet unless quiet.nil?
234
+ args = [_bind_dn, mechanism]
235
+ credential = nil
236
+ if need_credential_sasl_mechanism?(mechanism)
237
+ credential = password(_bind_dn, options)
238
+ end
239
+ if @sasl_options
240
+ credential ||= ""
241
+ args.concat([credential, nil, nil, @sasl_options])
242
+ else
243
+ args << credential if credential
244
+ end
245
+ info = {
246
+ :name => "bind: SASL", :dn => _bind_dn, :mechanism => mechanism
247
+ }
248
+ execute(:sasl_bind, info, *args)
249
+ true
250
+ ensure
251
+ @connection.sasl_quiet = sasl_quiet
252
+ end
253
+ end
254
+ end
255
+
256
+ def simple_bind(bind_dn, options={})
257
+ super do |_bind_dn, password|
258
+ execute(:bind, {:dn => _bind_dn}, _bind_dn, password)
259
+ true
260
+ end
261
+ end
262
+
263
+ def parse_entries(entries)
264
+ result = []
265
+ entries.each do |type, key, attributes|
266
+ mod_type = ensure_mod_type(type)
267
+ binary = schema.attribute(key).binary?
268
+ mod_type |= LDAP::LDAP_MOD_BVALUES if binary
269
+ attributes.each do |name, values|
270
+ additional_mod_type = 0
271
+ if values.any? {|value| Ldif::Attribute.binary_value?(value)}
272
+ additional_mod_type |= LDAP::LDAP_MOD_BVALUES
273
+ end
274
+ result << LDAP.mod(mod_type | additional_mod_type, name, values)
275
+ end
276
+ end
277
+ result
278
+ end
279
+
280
+ def ensure_mod_type(type)
281
+ case type
282
+ when :replace, :add, :delete
283
+ LDAP.const_get("LDAP_MOD_#{type.to_s.upcase}")
284
+ else
285
+ raise ArgumentError, _("unknown type: %s") % type
286
+ end
287
+ end
288
+ end
289
+ end
290
+ end