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,95 @@
1
+ module ActiveLdap
2
+ module ObjectClass
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ def classes
9
+ required_classes.collect do |name|
10
+ schema.object_class(name)
11
+ end
12
+ end
13
+ end
14
+
15
+ def add_class(*target_classes)
16
+ replace_class(classes + target_classes)
17
+ end
18
+
19
+ def ensure_recommended_classes
20
+ add_class(self.class.recommended_classes)
21
+ end
22
+
23
+ def remove_class(*target_classes)
24
+ replace_class(classes - target_classes)
25
+ end
26
+
27
+ def replace_class(*target_classes)
28
+ new_classes = target_classes.flatten.compact.uniq
29
+ assert_object_classes(new_classes)
30
+ if new_classes.sort != classes.sort
31
+ set_attribute('objectClass', new_classes)
32
+ clear_object_class_based_cache
33
+ end
34
+ end
35
+ alias_method(:classes=, :replace_class)
36
+
37
+ def classes
38
+ (get_attribute('objectClass', true) || []).dup
39
+ end
40
+
41
+ private
42
+ def assert_object_classes(new_classes)
43
+ assert_valid_object_class_value_type(new_classes)
44
+ assert_valid_object_class_value(new_classes)
45
+ assert_have_all_required_classes(new_classes)
46
+ end
47
+
48
+ def assert_valid_object_class_value_type(new_classes)
49
+ invalid_classes = new_classes.reject do |new_class|
50
+ new_class.is_a?(String)
51
+ end
52
+ unless invalid_classes.empty?
53
+ format = _("Value in objectClass array is not a String: %s")
54
+ invalid_classes_info = invalid_classes.collect do |invalid_class|
55
+ "#{invalid_class.class}: #{invalid_class.inspect}"
56
+ end.join(", ")
57
+ raise TypeError, format % invalid_classes_info
58
+ end
59
+ end
60
+
61
+ def assert_valid_object_class_value(new_classes)
62
+ _schema = schema
63
+ invalid_classes = new_classes.reject do |new_class|
64
+ !_schema.object_class(new_class).id.nil?
65
+ end
66
+ unless invalid_classes.empty?
67
+ format = _("unknown objectClass in LDAP server: %s")
68
+ message = format % invalid_classes.join(', ')
69
+ raise ObjectClassError, message
70
+ end
71
+ end
72
+
73
+ def assert_have_all_required_classes(new_classes)
74
+ _schema = schema
75
+ normalized_new_classes = new_classes.collect(&:downcase)
76
+ required_classes = self.class.required_classes
77
+ required_classes = required_classes.reject do |required_class_name|
78
+ normalized_new_classes.include?(required_class_name.downcase) or
79
+ (normalized_new_classes.find do |new_class|
80
+ required_class = _schema.object_class(required_class_name)
81
+ _schema.object_class(new_class).super_class?(required_class)
82
+ end)
83
+ end
84
+ unless required_classes.empty?
85
+ format = _("Can't remove required objectClass: %s")
86
+ required_class_names = required_classes.collect do |required_class|
87
+ required_class = _schema.object_class(required_class)
88
+ self.class.human_object_class_name(required_class)
89
+ end
90
+ message = format % required_class_names.join(", ")
91
+ raise RequiredObjectClassMissed, message
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,610 @@
1
+ module ActiveLdap
2
+ module Operations
3
+ class << self
4
+ def included(base)
5
+ super
6
+ base.class_eval do
7
+ extend(Common)
8
+ extend(Find)
9
+ extend(LDIF)
10
+ extend(Delete)
11
+ extend(Update)
12
+
13
+ include(Common)
14
+ include(Find)
15
+ include(LDIF)
16
+ include(Delete)
17
+ include(Update)
18
+ end
19
+ end
20
+ end
21
+
22
+ module Common
23
+ VALID_SEARCH_OPTIONS = [:attribute, :value, :filter, :prefix,
24
+ :classes, :scope, :limit, :attributes,
25
+ :sort_by, :order, :connection, :base]
26
+
27
+ def search(options={}, &block)
28
+ validate_search_options(options)
29
+ attr = options[:attribute]
30
+ value = options[:value] || '*'
31
+ filter = options[:filter]
32
+ prefix = options[:prefix]
33
+ classes = options[:classes]
34
+
35
+ value = value.first if value.is_a?(Array) and value.first.size == 1
36
+
37
+ _attr = nil
38
+ _prefix = nil
39
+ if attr.nil? or attr == dn_attribute
40
+ _attr, value, _prefix = split_search_value(value)
41
+ end
42
+ attr ||= _attr || ensure_search_attribute
43
+ prefix ||= _prefix
44
+ filter ||= [attr, value]
45
+ filter = [:and, filter, *object_class_filters(classes)]
46
+ _base = options[:base] ? [options[:base]] : [prefix, base]
47
+ _base = prepare_search_base(_base)
48
+ if options.has_key?(:ldap_scope)
49
+ message = _(":ldap_scope search option is deprecated. " \
50
+ "Use :scope instead.")
51
+ ActiveSupport::Deprecation.warn(message)
52
+ options[:scope] ||= options[:ldap_scope]
53
+ end
54
+ search_options = {
55
+ :base => _base,
56
+ :scope => options[:scope] || scope,
57
+ :filter => filter,
58
+ :limit => options[:limit],
59
+ :attributes => options[:attributes],
60
+ :sort_by => options[:sort_by] || sort_by,
61
+ :order => options[:order] || order,
62
+ }
63
+
64
+ options[:connection] ||= connection
65
+ values = []
66
+ options[:connection].search(search_options) do |dn, attrs|
67
+ attributes = {}
68
+ attrs.each do |key, _value|
69
+ normalized_attr, normalized_value =
70
+ normalize_attribute_options(key, _value)
71
+ attributes[normalized_attr] ||= []
72
+ attributes[normalized_attr].concat(normalized_value)
73
+ end
74
+ values << [dn, attributes]
75
+ end
76
+ values = values.collect {|_value| yield(_value)} if block_given?
77
+ values
78
+ end
79
+
80
+ def exist?(dn, options={})
81
+ attr, value, prefix = split_search_value(dn)
82
+
83
+ options_for_leaf = {
84
+ :attribute => attr,
85
+ :value => value,
86
+ :prefix => prefix,
87
+ :limit => 1,
88
+ }
89
+
90
+ attribute = attr || ensure_search_attribute
91
+ options_for_non_leaf = {
92
+ :attribute => attr,
93
+ :value => value,
94
+ :prefix => ["#{attribute}=#{value}", prefix].compact.join(","),
95
+ :limit => 1,
96
+ :scope => :base,
97
+ }
98
+
99
+ !search(options_for_leaf.merge(options)).empty? or
100
+ !search(options_for_non_leaf.merge(options)).empty?
101
+ end
102
+ alias_method :exists?, :exist?
103
+
104
+ def count(options={})
105
+ search(options).size
106
+ end
107
+
108
+ private
109
+ def validate_search_options(options)
110
+ options.assert_valid_keys(VALID_SEARCH_OPTIONS)
111
+ end
112
+
113
+ def extract_options_from_args!(args)
114
+ args.last.is_a?(Hash) ? args.pop : {}
115
+ end
116
+
117
+ def ensure_search_attribute(*candidates)
118
+ default_search_attribute || "objectClass"
119
+ end
120
+
121
+ def ensure_dn_attribute(target)
122
+ "#{dn_attribute}=" +
123
+ target.gsub(/^\s*#{Regexp.escape(dn_attribute)}\s*=\s*/i, '')
124
+ end
125
+
126
+ def ensure_base(target)
127
+ [truncate_base(target), base.to_s].reject do |component|
128
+ component.blank?
129
+ end.join(',')
130
+ end
131
+
132
+ def truncate_base(target)
133
+ return nil if target.blank?
134
+ return target if base.nil?
135
+
136
+ parsed_target = nil
137
+ if target.is_a?(DN)
138
+ parsed_target = target
139
+ elsif /,/ =~ target
140
+ begin
141
+ parsed_target = DN.parse(target)
142
+ rescue DistinguishedNameInvalid
143
+ end
144
+ end
145
+
146
+ return target if parsed_target.nil?
147
+ begin
148
+ (parsed_target - base).to_s
149
+ rescue ArgumentError
150
+ target
151
+ end
152
+ end
153
+
154
+ def prepare_search_base(components)
155
+ components.compact.collect do |component|
156
+ case component
157
+ when String
158
+ component
159
+ when DN
160
+ component.to_s
161
+ else
162
+ DN.new(*component).to_s
163
+ end
164
+ end.reject{|x| x.empty?}.join(",")
165
+ end
166
+
167
+ def object_class_filters(classes=nil)
168
+ expected_classes = (classes || required_classes).collect do |name|
169
+ Escape.ldap_filter_escape(name)
170
+ end
171
+ unexpected_classes = excluded_classes.collect do |name|
172
+ Escape.ldap_filter_escape(name)
173
+ end
174
+ filters = []
175
+ unless expected_classes.empty?
176
+ filters << ["objectClass", "=", *expected_classes]
177
+ end
178
+ unless unexpected_classes.empty?
179
+ filters << [:not, [:or, ["objectClass", "=", *unexpected_classes]]]
180
+ end
181
+ filters
182
+ end
183
+
184
+ def split_search_value(value)
185
+ attr = prefix = nil
186
+
187
+ begin
188
+ dn = DN.parse(value)
189
+ attr, value = dn.rdns.first.to_a.first
190
+ rest = dn.rdns[1..-1]
191
+ prefix = DN.new(*rest).to_s unless rest.empty?
192
+ rescue DistinguishedNameInputInvalid
193
+ return [attr, value, prefix]
194
+ rescue DistinguishedNameInvalid
195
+ begin
196
+ dn = DN.parse("DUMMY=#{value}")
197
+ _, value = dn.rdns.first.to_a.first
198
+ rest = dn.rdns[1..-1]
199
+ prefix = DN.new(*rest).to_s unless rest.empty?
200
+ rescue DistinguishedNameInvalid
201
+ end
202
+ end
203
+
204
+ prefix = nil if prefix == base
205
+ prefix = truncate_base(prefix) if prefix
206
+ [attr, value, prefix]
207
+ end
208
+ end
209
+
210
+ module Find
211
+ # find
212
+ #
213
+ # Finds the first match for value where |value| is the value of some
214
+ # |field|, or the wildcard match. This is only useful for derived classes.
215
+ # usage: Subclass.find(:all, :attribute => "cn", :value => "some*val")
216
+ # Subclass.find(:all, 'some*val')
217
+ def find(*args)
218
+ options = extract_options_from_args!(args)
219
+ args = [:first] if args.empty? and !options.empty?
220
+ case args.first
221
+ when :first
222
+ options[:value] ||= args[1]
223
+ find_initial(options)
224
+ when :last
225
+ options[:value] ||= args[1]
226
+ find_last(options)
227
+ when :all
228
+ options[:value] ||= args[1]
229
+ find_every(options)
230
+ else
231
+ find_from_dns(args, options)
232
+ end
233
+ end
234
+
235
+ # A convenience wrapper for <tt>find(:first,
236
+ # *args)</tt>. You can pass in all the same arguments
237
+ # to this method as you can to <tt>find(:first)</tt>.
238
+ def first(*args)
239
+ find(:first, *args)
240
+ end
241
+
242
+ # A convenience wrapper for <tt>find(:last,
243
+ # *args)</tt>. You can pass in all the same arguments
244
+ # to this method as you can to <tt>find(:last)</tt>.
245
+ def last(*args)
246
+ find(:last, *args)
247
+ end
248
+
249
+ # This is an alias for find(:all). You can pass in
250
+ # all the same arguments to this method as you can
251
+ # to find(:all)
252
+ def all(*args)
253
+ find(:all, *args)
254
+ end
255
+
256
+ private
257
+ def find_initial(options)
258
+ find_every(options.merge(:limit => 1)).first
259
+ end
260
+
261
+ def find_last(options)
262
+ order = options[:order] || self.order || 'ascend'
263
+ order = normalize_sort_order(order) == :ascend ? :descend : :ascend
264
+ find_initial(options.merge(:order => order))
265
+ end
266
+
267
+ def normalize_sort_order(value)
268
+ case value.to_s
269
+ when /\Aasc(?:end)?\z/i
270
+ :ascend
271
+ when /\Adesc(?:end)?\z/i
272
+ :descend
273
+ else
274
+ raise ArgumentError, _("Invalid order: %s") % value.inspect
275
+ end
276
+ end
277
+
278
+ def find_every(options)
279
+ options = options.dup
280
+ sort_by = options.delete(:sort_by) || self.sort_by
281
+ order = options.delete(:order) || self.order
282
+ limit = options.delete(:limit) if sort_by or order
283
+ options[:attributes] |= ["objectClass"] if options[:attributes]
284
+
285
+ results = search(options).collect do |dn, attrs|
286
+ instantiate([dn, attrs, {:connection => options[:connection]}])
287
+ end
288
+ return results if sort_by.nil? and order.nil?
289
+
290
+ sort_by ||= "dn"
291
+ if sort_by.downcase == "dn"
292
+ results = results.sort_by {|result| DN.parse(result.dn)}
293
+ else
294
+ results = results.sort_by {|result| result.send(sort_by)}
295
+ end
296
+
297
+ results.reverse! if normalize_sort_order(order || "ascend") == :descend
298
+ results = results[0, limit] if limit
299
+ results
300
+ end
301
+
302
+ def find_from_dns(dns, options)
303
+ expects_array = dns.first.is_a?(Array)
304
+ return [] if expects_array and dns.first.empty?
305
+
306
+ dns = dns.flatten.compact.uniq
307
+
308
+ case dns.size
309
+ when 0
310
+ raise EntryNotFound, _("Couldn't find %s without a DN") % name
311
+ when 1
312
+ result = find_one(dns.first, options)
313
+ expects_array ? [result] : result
314
+ else
315
+ find_some(dns, options)
316
+ end
317
+ end
318
+
319
+ def find_one(dn, options)
320
+ attr, value, prefix = split_search_value(dn)
321
+ filter = [attr || ensure_search_attribute,
322
+ Escape.ldap_filter_escape(value)]
323
+ filter = [:and, filter, options[:filter]] if options[:filter]
324
+ options = {:prefix => prefix}.merge(options.merge(:filter => filter))
325
+ result = find_initial(options)
326
+ if result
327
+ result
328
+ else
329
+ args = [self.is_a?(Class) ? name : self.class.name,
330
+ dn]
331
+ if options[:filter]
332
+ format = _("Couldn't find %s: DN: %s: filter: %s")
333
+ args << options[:filter].inspect
334
+ else
335
+ format = _("Couldn't find %s: DN: %s")
336
+ end
337
+ raise EntryNotFound, format % args
338
+ end
339
+ end
340
+
341
+ def find_some(dns, options)
342
+ dn_filters = dns.collect do |dn|
343
+ attr, value, prefix = split_search_value(dn)
344
+ attr ||= ensure_search_attribute
345
+ filter = [attr, value]
346
+ if prefix
347
+ filter = [:and,
348
+ filter,
349
+ [dn, "*,#{Escape.ldap_filter_escape(prefix)},#{base}"]]
350
+ end
351
+ filter
352
+ end
353
+ filter = [:or, *dn_filters]
354
+ filter = [:and, filter, options[:filter]] if options[:filter]
355
+ result = find_every(options.merge(:filter => filter))
356
+ if result.size == dns.size
357
+ result
358
+ else
359
+ args = [self.is_a?(Class) ? name : self.class.name,
360
+ dns.join(", ")]
361
+ if options[:filter]
362
+ format = _("Couldn't find all %s: DNs (%s): filter: %s")
363
+ args << options[:filter].inspect
364
+ else
365
+ format = _("Couldn't find all %s: DNs (%s)")
366
+ end
367
+ raise EntryNotFound, format % args
368
+ end
369
+ end
370
+
371
+ def ensure_dn(target)
372
+ attr, value, prefix = split_search_value(target)
373
+ "#{attr || dn_attribute}=#{value},#{prefix || base}"
374
+ end
375
+ end
376
+
377
+ module LDIF
378
+ def dump(options={})
379
+ ldif = Ldif.new
380
+ options = {:base => base, :scope => scope}.merge(options)
381
+ options[:connection] ||= connection
382
+ options[:connection].search(options) do |dn, attributes|
383
+ ldif << Ldif::Record.new(dn, attributes)
384
+ end
385
+ return "" if ldif.records.empty?
386
+ ldif.to_s
387
+ end
388
+
389
+ def to_ldif_record(dn, attributes)
390
+ Ldif::Record.new(dn, attributes)
391
+ end
392
+
393
+ def to_ldif(dn, attributes)
394
+ Ldif.new([to_ldif_record(dn, attributes)]).to_s
395
+ end
396
+
397
+ def load(ldif, options={})
398
+ return if ldif.blank?
399
+ Ldif.parse(ldif).each do |record|
400
+ record.load(self, options)
401
+ end
402
+ end
403
+
404
+ module ContentRecordLoadable
405
+ def load(operator, options)
406
+ operator.add_entry(dn, attributes, options)
407
+ end
408
+ end
409
+ Ldif::ContentRecord.send(:include, ContentRecordLoadable)
410
+
411
+ module AddRecordLoadable
412
+ def load(operator, options)
413
+ entries = attributes.collect do |key, value|
414
+ [:add, key, value]
415
+ end
416
+ options = {:controls => controls}.merge(options)
417
+ operator.modify_entry(dn, entries, options)
418
+ end
419
+ end
420
+ Ldif::AddRecord.send(:include, AddRecordLoadable)
421
+
422
+ module DeleteRecordLoadable
423
+ def load(operator, options)
424
+ operator.delete_entry(dn, {:controls => controls}.merge(options))
425
+ end
426
+ end
427
+ Ldif::DeleteRecord.send(:include, DeleteRecordLoadable)
428
+
429
+ module ModifyNameRecordLoadable
430
+ def load(operator, options)
431
+ operator.modify_rdn_entry(dn, new_rdn, delete_old_rdn?, new_superior,
432
+ {:controls => controls}.merge(options))
433
+ end
434
+ end
435
+ Ldif::ModifyNameRecord.send(:include, ModifyNameRecordLoadable)
436
+
437
+ module ModifyRecordLoadable
438
+ def load(operator, options)
439
+ modify_entries = operations.inject([]) do |result, operation|
440
+ result + operation.to_modify_entries
441
+ end
442
+ return if modify_entries.empty?
443
+ operator.modify_entry(dn, modify_entries,
444
+ {:controls => controls}.merge(options))
445
+ end
446
+
447
+ module AddOperationModifiable
448
+ def to_modify_entries
449
+ attributes.collect do |key, value|
450
+ [:add, key, value]
451
+ end
452
+ end
453
+ end
454
+ Ldif::ModifyRecord::AddOperation.send(:include, AddOperationModifiable)
455
+
456
+ module DeleteOperationModifiable
457
+ def to_modify_entries
458
+ return [[:delete, full_attribute_name, []]] if attributes.empty?
459
+ attributes.collect do |key, value|
460
+ [:delete, key, value]
461
+ end
462
+ end
463
+ end
464
+ Ldif::ModifyRecord::DeleteOperation.send(:include,
465
+ DeleteOperationModifiable)
466
+
467
+ module ReplaceOperationModifiable
468
+ def to_modify_entries
469
+ return [[:replace, full_attribute_name, []]] if attributes.empty?
470
+ attributes.collect do |key, value|
471
+ [:replace, key, value]
472
+ end
473
+ end
474
+ end
475
+ Ldif::ModifyRecord::ReplaceOperation.send(:include,
476
+ ReplaceOperationModifiable)
477
+ end
478
+ Ldif::ModifyRecord.send(:include, ModifyRecordLoadable)
479
+ end
480
+
481
+ module Delete
482
+ def destroy(targets, options={})
483
+ targets = [targets] unless targets.is_a?(Array)
484
+ targets.each do |target|
485
+ find(target, options).destroy
486
+ end
487
+ end
488
+
489
+ def destroy_all(options_or_filter=nil, deprecated_options=nil)
490
+ if deprecated_options.nil?
491
+ if options_or_filter.is_a?(String)
492
+ options = {:filter => options_or_filter}
493
+ else
494
+ options = (options_or_filter || {}).dup
495
+ end
496
+ else
497
+ options = deprecated_options.merge(:filter => options_or_filter)
498
+ end
499
+
500
+ find(:all, options).sort_by do |target|
501
+ target.dn
502
+ end.each do |target|
503
+ target.destroy
504
+ end
505
+ end
506
+
507
+ def delete(targets, options={})
508
+ targets = [targets] unless targets.is_a?(Array)
509
+ targets = targets.collect do |target|
510
+ ensure_dn_attribute(ensure_base(target))
511
+ end
512
+ delete_entry(targets, options)
513
+ end
514
+
515
+ def delete_entry(dn, options={})
516
+ options[:connection] ||= connection
517
+ begin
518
+ options[:connection].delete(dn, options)
519
+ rescue Error
520
+ format = _("Failed to delete LDAP entry: <%s>: %s")
521
+ raise DeleteError.new(format % [dn.inspect, $!.message])
522
+ end
523
+ end
524
+
525
+ def delete_all(options_or_filter=nil, deprecated_options=nil)
526
+ if deprecated_options.nil?
527
+ if options_or_filter.is_a?(String)
528
+ options = {:filter => options_or_filter}
529
+ else
530
+ options = (options_or_filter || {}).dup
531
+ end
532
+ else
533
+ options = deprecated_options.merge(:filter => options_or_filter)
534
+ end
535
+ targets = search(options).collect do |dn, attributes|
536
+ dn
537
+ end.sort_by do |dn|
538
+ dn.upcase.reverse
539
+ end.reverse
540
+
541
+ delete_entry(targets, options)
542
+ end
543
+ end
544
+
545
+ module Update
546
+ def add_entry(dn, attributes, options={})
547
+ unnormalized_attributes = attributes.collect do |key, value|
548
+ [:add, key, unnormalize_attribute(key, value)]
549
+ end
550
+ options[:connection] ||= connection
551
+ options[:connection].add(dn, unnormalized_attributes, options)
552
+ end
553
+
554
+ def modify_entry(dn, attributes, options={})
555
+ return if attributes.empty?
556
+ unnormalized_attributes = attributes.collect do |type, key, value|
557
+ [type, key, unnormalize_attribute(key, value)]
558
+ end
559
+ options[:connection] ||= connection
560
+ options[:connection].modify(dn, unnormalized_attributes, options)
561
+ end
562
+
563
+ def modify_rdn_entry(dn, new_rdn, delete_old_rdn, new_superior, options={})
564
+ options[:connection] ||= connection
565
+ options[:connection].modify_rdn(dn, new_rdn, delete_old_rdn,
566
+ new_superior, options)
567
+ end
568
+
569
+ def update(dn, attributes, options={})
570
+ if dn.is_a?(Array)
571
+ i = -1
572
+ dns = dn
573
+ dns.collect do |_dn|
574
+ i += 1
575
+ update(_dn, attributes[i], options)
576
+ end
577
+ else
578
+ object = find(dn, options)
579
+ object.update_attributes(attributes)
580
+ object
581
+ end
582
+ end
583
+
584
+ def update_all(attributes, filter=nil, options={})
585
+ search_options = options.dup
586
+ if filter
587
+ if filter.is_a?(String) and /[=\(\)&\|]/ !~ filter
588
+ search_options = search_options.merge(:value => filter)
589
+ else
590
+ search_options = search_options.merge(:filter => filter)
591
+ end
592
+ end
593
+ targets = search(search_options).collect do |dn, attrs|
594
+ dn
595
+ end
596
+
597
+ unnormalized_attributes = attributes.collect do |name, value|
598
+ normalized_name, normalized_value = normalize_attribute(name, value)
599
+ [:replace, normalized_name,
600
+ unnormalize_attribute(normalized_name, normalized_value)]
601
+ end
602
+ options[:connection] ||= connection
603
+ conn = options[:connection]
604
+ targets.each do |dn|
605
+ conn.modify(dn, unnormalized_attributes, options)
606
+ end
607
+ end
608
+ end
609
+ end
610
+ end