activeldap 0.9.0

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 (435) hide show
  1. data/CHANGES +454 -0
  2. data/COPYING +340 -0
  3. data/LICENSE +58 -0
  4. data/README +101 -0
  5. data/Rakefile +175 -0
  6. data/TODO +25 -0
  7. data/benchmark/bench-al.rb +202 -0
  8. data/benchmark/config.yaml.sample +5 -0
  9. data/data/locale/en/LC_MESSAGES/active-ldap.mo +0 -0
  10. data/data/locale/ja/LC_MESSAGES/active-ldap.mo +0 -0
  11. data/examples/al-admin/README +182 -0
  12. data/examples/al-admin/Rakefile +10 -0
  13. data/examples/al-admin/app/controllers/account_controller.rb +59 -0
  14. data/examples/al-admin/app/controllers/application.rb +34 -0
  15. data/examples/al-admin/app/controllers/attributes_controller.rb +17 -0
  16. data/examples/al-admin/app/controllers/directory_controller.rb +47 -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 +51 -0
  20. data/examples/al-admin/app/controllers/welcome_controller.rb +10 -0
  21. data/examples/al-admin/app/helpers/account_helper.rb +2 -0
  22. data/examples/al-admin/app/helpers/application_helper.rb +42 -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 +13 -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 +54 -0
  32. data/examples/al-admin/app/models/user.rb +91 -0
  33. data/examples/al-admin/app/views/_entry/_attributes_information.rhtml +23 -0
  34. data/examples/al-admin/app/views/_entry/_entry.rhtml +15 -0
  35. data/examples/al-admin/app/views/_schema/_aliases.rhtml +7 -0
  36. data/examples/al-admin/app/views/_switcher/_after.rhtml +2 -0
  37. data/examples/al-admin/app/views/_switcher/_before.rhtml +5 -0
  38. data/examples/al-admin/app/views/account/login.rhtml +26 -0
  39. data/examples/al-admin/app/views/account/sign_up.rhtml +28 -0
  40. data/examples/al-admin/app/views/attributes/_attributes.rhtml +19 -0
  41. data/examples/al-admin/app/views/attributes/_detail.rhtml +29 -0
  42. data/examples/al-admin/app/views/attributes/index.rhtml +3 -0
  43. data/examples/al-admin/app/views/attributes/show.rhtml +31 -0
  44. data/examples/al-admin/app/views/directory/_tree.rhtml +10 -0
  45. data/examples/al-admin/app/views/directory/_tree_view_js.rhtml +26 -0
  46. data/examples/al-admin/app/views/directory/index.rhtml +13 -0
  47. data/examples/al-admin/app/views/directory/populate.rhtml +2 -0
  48. data/examples/al-admin/app/views/layouts/_flash_box.rhtml +4 -0
  49. data/examples/al-admin/app/views/layouts/_footer.rhtml +9 -0
  50. data/examples/al-admin/app/views/layouts/_header_menu.rhtml +10 -0
  51. data/examples/al-admin/app/views/layouts/_main_menu.rhtml +18 -0
  52. data/examples/al-admin/app/views/layouts/application.rhtml +56 -0
  53. data/examples/al-admin/app/views/object_classes/_attributes.rhtml +28 -0
  54. data/examples/al-admin/app/views/object_classes/_object_classes.rhtml +19 -0
  55. data/examples/al-admin/app/views/object_classes/index.rhtml +3 -0
  56. data/examples/al-admin/app/views/object_classes/show.rhtml +39 -0
  57. data/examples/al-admin/app/views/syntaxes/_detail.rhtml +14 -0
  58. data/examples/al-admin/app/views/syntaxes/_syntaxes.rhtml +19 -0
  59. data/examples/al-admin/app/views/syntaxes/index.rhtml +3 -0
  60. data/examples/al-admin/app/views/syntaxes/show.rhtml +22 -0
  61. data/examples/al-admin/app/views/users/_attributes_update_form.rhtml +30 -0
  62. data/examples/al-admin/app/views/users/_form.rhtml +13 -0
  63. data/examples/al-admin/app/views/users/_object_classes_update_form.rhtml +40 -0
  64. data/examples/al-admin/app/views/users/_password_change_form.rhtml +20 -0
  65. data/examples/al-admin/app/views/users/edit.rhtml +15 -0
  66. data/examples/al-admin/app/views/users/index.rhtml +10 -0
  67. data/examples/al-admin/app/views/users/show.rhtml +11 -0
  68. data/examples/al-admin/app/views/welcome/index.rhtml +13 -0
  69. data/examples/al-admin/config/boot.rb +45 -0
  70. data/examples/al-admin/config/database.yml.example +19 -0
  71. data/examples/al-admin/config/environment.rb +70 -0
  72. data/examples/al-admin/config/environments/development.rb +21 -0
  73. data/examples/al-admin/config/environments/production.rb +18 -0
  74. data/examples/al-admin/config/environments/test.rb +19 -0
  75. data/examples/al-admin/config/ldap.yml.example +21 -0
  76. data/examples/al-admin/config/routes.rb +46 -0
  77. data/examples/al-admin/db/migrate/001_create_users.rb +16 -0
  78. data/examples/al-admin/lib/accept_http_rails_relative_url_root.rb +9 -0
  79. data/examples/al-admin/lib/authenticated_system.rb +124 -0
  80. data/examples/al-admin/lib/authenticated_test_helper.rb +113 -0
  81. data/examples/al-admin/lib/tasks/gettext.rake +35 -0
  82. data/examples/al-admin/po/en/al-admin.po +341 -0
  83. data/examples/al-admin/po/ja/al-admin.po +341 -0
  84. data/examples/al-admin/po/nl/al-admin.po +373 -0
  85. data/examples/al-admin/public/.htaccess +40 -0
  86. data/examples/al-admin/public/404.html +30 -0
  87. data/examples/al-admin/public/500.html +30 -0
  88. data/examples/al-admin/public/dispatch.cgi +10 -0
  89. data/examples/al-admin/public/dispatch.fcgi +24 -0
  90. data/examples/al-admin/public/dispatch.rb +10 -0
  91. data/examples/al-admin/public/favicon.ico +0 -0
  92. data/examples/al-admin/public/images/active-ldap.svg +6351 -0
  93. data/examples/al-admin/public/images/al-admin.png +0 -0
  94. data/examples/al-admin/public/images/al-admin.svg +6371 -0
  95. data/examples/al-admin/public/images/header-background.png +0 -0
  96. data/examples/al-admin/public/images/header-background.svg +99 -0
  97. data/examples/al-admin/public/images/rails.png +0 -0
  98. data/examples/al-admin/public/images/spinelz/accordion_tab_left_active.gif +0 -0
  99. data/examples/al-admin/public/images/spinelz/accordion_tab_left_inactive.gif +0 -0
  100. data/examples/al-admin/public/images/spinelz/accordion_tab_middle_active.gif +0 -0
  101. data/examples/al-admin/public/images/spinelz/accordion_tab_middle_inactive.gif +0 -0
  102. data/examples/al-admin/public/images/spinelz/accordion_tab_right_active.gif +0 -0
  103. data/examples/al-admin/public/images/spinelz/accordion_tab_right_inactive.gif +0 -0
  104. data/examples/al-admin/public/images/spinelz/balloon_back.gif +0 -0
  105. data/examples/al-admin/public/images/spinelz/balloon_bottom_left.gif +0 -0
  106. data/examples/al-admin/public/images/spinelz/balloon_bottom_middle.gif +0 -0
  107. data/examples/al-admin/public/images/spinelz/balloon_bottom_right.gif +0 -0
  108. data/examples/al-admin/public/images/spinelz/balloon_left_down_arrow.gif +0 -0
  109. data/examples/al-admin/public/images/spinelz/balloon_left_up_arrow.gif +0 -0
  110. data/examples/al-admin/public/images/spinelz/balloon_middle_left.gif +0 -0
  111. data/examples/al-admin/public/images/spinelz/balloon_middle_right.gif +0 -0
  112. data/examples/al-admin/public/images/spinelz/balloon_right_down_arrow.gif +0 -0
  113. data/examples/al-admin/public/images/spinelz/balloon_right_up_arrow.gif +0 -0
  114. data/examples/al-admin/public/images/spinelz/balloon_top_left.gif +0 -0
  115. data/examples/al-admin/public/images/spinelz/balloon_top_middle.gif +0 -0
  116. data/examples/al-admin/public/images/spinelz/balloon_top_right.gif +0 -0
  117. data/examples/al-admin/public/images/spinelz/barchart_h.gif +0 -0
  118. data/examples/al-admin/public/images/spinelz/barchart_v.gif +0 -0
  119. data/examples/al-admin/public/images/spinelz/button.gif +0 -0
  120. data/examples/al-admin/public/images/spinelz/calendar_default_handler.gif +0 -0
  121. data/examples/al-admin/public/images/spinelz/calendar_delete.gif +0 -0
  122. data/examples/al-admin/public/images/spinelz/calendar_next.gif +0 -0
  123. data/examples/al-admin/public/images/spinelz/calendar_next_second.gif +0 -0
  124. data/examples/al-admin/public/images/spinelz/calendar_pre.gif +0 -0
  125. data/examples/al-admin/public/images/spinelz/calendar_pre_second.gif +0 -0
  126. data/examples/al-admin/public/images/spinelz/calendar_private_icon.gif +0 -0
  127. data/examples/al-admin/public/images/spinelz/calendar_schedule.gif +0 -0
  128. data/examples/al-admin/public/images/spinelz/calender_back.gif +0 -0
  129. data/examples/al-admin/public/images/spinelz/calender_back_second.gif +0 -0
  130. data/examples/al-admin/public/images/spinelz/datepicker2_back.gif +0 -0
  131. data/examples/al-admin/public/images/spinelz/datepicker2_back_second.gif +0 -0
  132. data/examples/al-admin/public/images/spinelz/datepicker2_next.gif +0 -0
  133. data/examples/al-admin/public/images/spinelz/datepicker2_next_second.gif +0 -0
  134. data/examples/al-admin/public/images/spinelz/datepicker2_pre.gif +0 -0
  135. data/examples/al-admin/public/images/spinelz/datepicker2_pre_second.gif +0 -0
  136. data/examples/al-admin/public/images/spinelz/datepicker_back.gif +0 -0
  137. data/examples/al-admin/public/images/spinelz/datepicker_back_second.gif +0 -0
  138. data/examples/al-admin/public/images/spinelz/datepicker_next.gif +0 -0
  139. data/examples/al-admin/public/images/spinelz/datepicker_next_second.gif +0 -0
  140. data/examples/al-admin/public/images/spinelz/datepicker_pre.gif +0 -0
  141. data/examples/al-admin/public/images/spinelz/datepicker_pre_second.gif +0 -0
  142. data/examples/al-admin/public/images/spinelz/grid_down.gif +0 -0
  143. data/examples/al-admin/public/images/spinelz/grid_state.gif +0 -0
  144. data/examples/al-admin/public/images/spinelz/grid_up.gif +0 -0
  145. data/examples/al-admin/public/images/spinelz/icon_day.gif +0 -0
  146. data/examples/al-admin/public/images/spinelz/icon_month.gif +0 -0
  147. data/examples/al-admin/public/images/spinelz/icon_week.gif +0 -0
  148. data/examples/al-admin/public/images/spinelz/menubar_back.gif +0 -0
  149. data/examples/al-admin/public/images/spinelz/menubar_subcontents_back.gif +0 -0
  150. data/examples/al-admin/public/images/spinelz/navPanel_tab_left_active.gif +0 -0
  151. data/examples/al-admin/public/images/spinelz/navPanel_tab_left_inactive.gif +0 -0
  152. data/examples/al-admin/public/images/spinelz/navPanel_tab_middle_active.gif +0 -0
  153. data/examples/al-admin/public/images/spinelz/navPanel_tab_middle_inactive.gif +0 -0
  154. data/examples/al-admin/public/images/spinelz/navPanel_tab_right_active.gif +0 -0
  155. data/examples/al-admin/public/images/spinelz/navPanel_tab_right_inactive.gif +0 -0
  156. data/examples/al-admin/public/images/spinelz/select_date.gif +0 -0
  157. data/examples/al-admin/public/images/spinelz/selectabletable_selected.gif +0 -0
  158. data/examples/al-admin/public/images/spinelz/sideBarBox_about.gif +0 -0
  159. data/examples/al-admin/public/images/spinelz/sideBarBox_menu.gif +0 -0
  160. data/examples/al-admin/public/images/spinelz/sideBarBox_sample.gif +0 -0
  161. data/examples/al-admin/public/images/spinelz/sideBarBox_tabBottomActive.gif +0 -0
  162. data/examples/al-admin/public/images/spinelz/sideBarBox_tabBottomInactive.gif +0 -0
  163. data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleActive.gif +0 -0
  164. data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleActive2.gif +0 -0
  165. data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleInactive.gif +0 -0
  166. data/examples/al-admin/public/images/spinelz/sideBarBox_tabMiddleInactive2.gif +0 -0
  167. data/examples/al-admin/public/images/spinelz/sideBarBox_tabTopActive.gif +0 -0
  168. data/examples/al-admin/public/images/spinelz/sideBarBox_tabTopInactive.gif +0 -0
  169. data/examples/al-admin/public/images/spinelz/sideBarBox_tabbar.gif +0 -0
  170. data/examples/al-admin/public/images/spinelz/sortableTable_down.gif +0 -0
  171. data/examples/al-admin/public/images/spinelz/sortableTable_normal.gif +0 -0
  172. data/examples/al-admin/public/images/spinelz/sortableTable_up.gif +0 -0
  173. data/examples/al-admin/public/images/spinelz/switcher_close.gif +0 -0
  174. data/examples/al-admin/public/images/spinelz/switcher_open.gif +0 -0
  175. data/examples/al-admin/public/images/spinelz/tabBox_close.gif +0 -0
  176. data/examples/al-admin/public/images/spinelz/tabBox_tabLeftActive.gif +0 -0
  177. data/examples/al-admin/public/images/spinelz/tabBox_tabLeftInactive.gif +0 -0
  178. data/examples/al-admin/public/images/spinelz/tabBox_tabMiddleActive.gif +0 -0
  179. data/examples/al-admin/public/images/spinelz/tabBox_tabMiddleInactive.gif +0 -0
  180. data/examples/al-admin/public/images/spinelz/tabBox_tabRightActive.gif +0 -0
  181. data/examples/al-admin/public/images/spinelz/tabBox_tabRightInactive.gif +0 -0
  182. data/examples/al-admin/public/images/spinelz/tab_bar.gif +0 -0
  183. data/examples/al-admin/public/images/spinelz/table_back.gif +0 -0
  184. data/examples/al-admin/public/images/spinelz/timepicker_clock.gif +0 -0
  185. data/examples/al-admin/public/images/spinelz/toolbar_close.gif +0 -0
  186. data/examples/al-admin/public/images/spinelz/toolbar_left.gif +0 -0
  187. data/examples/al-admin/public/images/spinelz/toolbar_max.gif +0 -0
  188. data/examples/al-admin/public/images/spinelz/toolbar_middle.gif +0 -0
  189. data/examples/al-admin/public/images/spinelz/toolbar_min.gif +0 -0
  190. data/examples/al-admin/public/images/spinelz/toolbar_next.gif +0 -0
  191. data/examples/al-admin/public/images/spinelz/toolbar_right.gif +0 -0
  192. data/examples/al-admin/public/images/spinelz/treeview_dir.gif +0 -0
  193. data/examples/al-admin/public/images/spinelz/treeview_file.gif +0 -0
  194. data/examples/al-admin/public/images/spinelz/treeview_group.gif +0 -0
  195. data/examples/al-admin/public/images/spinelz/treeview_group_special.gif +0 -0
  196. data/examples/al-admin/public/images/spinelz/treeview_state.gif +0 -0
  197. data/examples/al-admin/public/images/spinelz/treeview_user.gif +0 -0
  198. data/examples/al-admin/public/images/spinelz/window_bottom_left.gif +0 -0
  199. data/examples/al-admin/public/images/spinelz/window_bottom_middle.gif +0 -0
  200. data/examples/al-admin/public/images/spinelz/window_bottom_right.gif +0 -0
  201. data/examples/al-admin/public/images/spinelz/window_close.gif +0 -0
  202. data/examples/al-admin/public/images/spinelz/window_max.gif +0 -0
  203. data/examples/al-admin/public/images/spinelz/window_middle_left.gif +0 -0
  204. data/examples/al-admin/public/images/spinelz/window_middle_right.gif +0 -0
  205. data/examples/al-admin/public/images/spinelz/window_min.gif +0 -0
  206. data/examples/al-admin/public/images/spinelz/window_top_left.gif +0 -0
  207. data/examples/al-admin/public/images/spinelz/window_top_middle.gif +0 -0
  208. data/examples/al-admin/public/images/spinelz/window_top_right.gif +0 -0
  209. data/examples/al-admin/public/javascripts/application.js +2 -0
  210. data/examples/al-admin/public/javascripts/controls.js +833 -0
  211. data/examples/al-admin/public/javascripts/dragdrop.js +942 -0
  212. data/examples/al-admin/public/javascripts/effects.js +1088 -0
  213. data/examples/al-admin/public/javascripts/prototype.js +2515 -0
  214. data/examples/al-admin/public/javascripts/spinelz/accordion.js +185 -0
  215. data/examples/al-admin/public/javascripts/spinelz/ajaxHistory.js +157 -0
  216. data/examples/al-admin/public/javascripts/spinelz/balloon.js +287 -0
  217. data/examples/al-admin/public/javascripts/spinelz/barchart.js +524 -0
  218. data/examples/al-admin/public/javascripts/spinelz/calendar.js +3012 -0
  219. data/examples/al-admin/public/javascripts/spinelz/colorpicker.js +128 -0
  220. data/examples/al-admin/public/javascripts/spinelz/datepicker.js +438 -0
  221. data/examples/al-admin/public/javascripts/spinelz/grid.js +1391 -0
  222. data/examples/al-admin/public/javascripts/spinelz/grid_resizeEx.js +100 -0
  223. data/examples/al-admin/public/javascripts/spinelz/grid_sortabletableEx.js +129 -0
  224. data/examples/al-admin/public/javascripts/spinelz/inplaceEditorEx.js +148 -0
  225. data/examples/al-admin/public/javascripts/spinelz/menubar.js +232 -0
  226. data/examples/al-admin/public/javascripts/spinelz/navPanel.js +170 -0
  227. data/examples/al-admin/public/javascripts/spinelz/selectableTable.js +433 -0
  228. data/examples/al-admin/public/javascripts/spinelz/sideBarBox.js +282 -0
  229. data/examples/al-admin/public/javascripts/spinelz/sideBarBox_effects.js +83 -0
  230. data/examples/al-admin/public/javascripts/spinelz/sortableTable.js +270 -0
  231. data/examples/al-admin/public/javascripts/spinelz/switcher.js +78 -0
  232. data/examples/al-admin/public/javascripts/spinelz/tabBox.js +469 -0
  233. data/examples/al-admin/public/javascripts/spinelz/timepicker.js +384 -0
  234. data/examples/al-admin/public/javascripts/spinelz/toolbar.js +152 -0
  235. data/examples/al-admin/public/javascripts/spinelz/treeview.js +703 -0
  236. data/examples/al-admin/public/javascripts/spinelz/window.js +641 -0
  237. data/examples/al-admin/public/javascripts/spinelz/window_resizeEx.js +130 -0
  238. data/examples/al-admin/public/javascripts/spinelz_lib/builder.js +131 -0
  239. data/examples/al-admin/public/javascripts/spinelz_lib/controls.js +835 -0
  240. data/examples/al-admin/public/javascripts/spinelz_lib/dragdrop.js +944 -0
  241. data/examples/al-admin/public/javascripts/spinelz_lib/effects.js +1090 -0
  242. data/examples/al-admin/public/javascripts/spinelz_lib/json.js +139 -0
  243. data/examples/al-admin/public/javascripts/spinelz_lib/prototype.js +2515 -0
  244. data/examples/al-admin/public/javascripts/spinelz_lib/resize.js +215 -0
  245. data/examples/al-admin/public/javascripts/spinelz_lib/scriptaculous.js +51 -0
  246. data/examples/al-admin/public/javascripts/spinelz_lib/slider.js +278 -0
  247. data/examples/al-admin/public/javascripts/spinelz_lib/spinelz_util.js +1266 -0
  248. data/examples/al-admin/public/javascripts/spinelz_lib/unittest.js +564 -0
  249. data/examples/al-admin/public/robots.txt +1 -0
  250. data/examples/al-admin/public/stylesheets/account.css +41 -0
  251. data/examples/al-admin/public/stylesheets/attributes.css +1 -0
  252. data/examples/al-admin/public/stylesheets/base.css +99 -0
  253. data/examples/al-admin/public/stylesheets/common.css +2 -0
  254. data/examples/al-admin/public/stylesheets/detail.css +36 -0
  255. data/examples/al-admin/public/stylesheets/directory.css +22 -0
  256. data/examples/al-admin/public/stylesheets/object-classes.css +6 -0
  257. data/examples/al-admin/public/stylesheets/rails.css +35 -0
  258. data/examples/al-admin/public/stylesheets/spinelz/accordion.css +59 -0
  259. data/examples/al-admin/public/stylesheets/spinelz/balloon.css +151 -0
  260. data/examples/al-admin/public/stylesheets/spinelz/calendar.css +564 -0
  261. data/examples/al-admin/public/stylesheets/spinelz/datepicker.css +175 -0
  262. data/examples/al-admin/public/stylesheets/spinelz/grid.css +137 -0
  263. data/examples/al-admin/public/stylesheets/spinelz/menubar.css +78 -0
  264. data/examples/al-admin/public/stylesheets/spinelz/modal.css +22 -0
  265. data/examples/al-admin/public/stylesheets/spinelz/navPanel.css +58 -0
  266. data/examples/al-admin/public/stylesheets/spinelz/selectableTable.css +28 -0
  267. data/examples/al-admin/public/stylesheets/spinelz/sideBarBox.css +82 -0
  268. data/examples/al-admin/public/stylesheets/spinelz/sortableTable.css +51 -0
  269. data/examples/al-admin/public/stylesheets/spinelz/switcher.css +23 -0
  270. data/examples/al-admin/public/stylesheets/spinelz/tabBox.css +94 -0
  271. data/examples/al-admin/public/stylesheets/spinelz/timepicker.css +508 -0
  272. data/examples/al-admin/public/stylesheets/spinelz/toolbar.css +82 -0
  273. data/examples/al-admin/public/stylesheets/spinelz/treeview.css +121 -0
  274. data/examples/al-admin/public/stylesheets/spinelz/window.css +140 -0
  275. data/examples/al-admin/public/stylesheets/structure.css +81 -0
  276. data/examples/al-admin/public/stylesheets/syntaxes.css +1 -0
  277. data/examples/al-admin/public/stylesheets/users.css +13 -0
  278. data/examples/al-admin/public/stylesheets/welcome.css +0 -0
  279. data/examples/al-admin/script/about +3 -0
  280. data/examples/al-admin/script/breakpointer +3 -0
  281. data/examples/al-admin/script/console +3 -0
  282. data/examples/al-admin/script/destroy +3 -0
  283. data/examples/al-admin/script/generate +3 -0
  284. data/examples/al-admin/script/performance/benchmarker +3 -0
  285. data/examples/al-admin/script/performance/profiler +3 -0
  286. data/examples/al-admin/script/plugin +3 -0
  287. data/examples/al-admin/script/process/inspector +3 -0
  288. data/examples/al-admin/script/process/reaper +3 -0
  289. data/examples/al-admin/script/process/spawner +3 -0
  290. data/examples/al-admin/script/runner +3 -0
  291. data/examples/al-admin/script/server +3 -0
  292. data/examples/al-admin/test/fixtures/users.yml +9 -0
  293. data/examples/al-admin/test/functional/account_controller_test.rb +24 -0
  294. data/examples/al-admin/test/functional/attributes_controller_test.rb +18 -0
  295. data/examples/al-admin/test/functional/directory_controller_test.rb +18 -0
  296. data/examples/al-admin/test/functional/object_classes_controller_test.rb +18 -0
  297. data/examples/al-admin/test/functional/syntaxes_controller_test.rb +18 -0
  298. data/examples/al-admin/test/functional/users_controller_test.rb +18 -0
  299. data/examples/al-admin/test/functional/welcome_controller_test.rb +18 -0
  300. data/examples/al-admin/test/run-test.sh +3 -0
  301. data/examples/al-admin/test/test_helper.rb +28 -0
  302. data/examples/al-admin/test/unit/user_test.rb +13 -0
  303. data/examples/al-admin/vendor/plugins/exception_notification/README +111 -0
  304. data/examples/al-admin/vendor/plugins/exception_notification/init.rb +1 -0
  305. data/examples/al-admin/vendor/plugins/exception_notification/lib/exception_notifiable.rb +99 -0
  306. data/examples/al-admin/vendor/plugins/exception_notification/lib/exception_notifier.rb +67 -0
  307. data/examples/al-admin/vendor/plugins/exception_notification/lib/exception_notifier_helper.rb +77 -0
  308. data/examples/al-admin/vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb +61 -0
  309. data/examples/al-admin/vendor/plugins/exception_notification/test/test_helper.rb +7 -0
  310. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml +1 -0
  311. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml +7 -0
  312. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml +16 -0
  313. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml +3 -0
  314. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml +2 -0
  315. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml +3 -0
  316. data/examples/al-admin/vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml +6 -0
  317. data/examples/config.yaml.example +5 -0
  318. data/examples/example.der +0 -0
  319. data/examples/example.jpg +0 -0
  320. data/examples/groupadd +41 -0
  321. data/examples/groupdel +35 -0
  322. data/examples/groupls +49 -0
  323. data/examples/groupmod +42 -0
  324. data/examples/lpasswd +55 -0
  325. data/examples/objects/group.rb +13 -0
  326. data/examples/objects/ou.rb +4 -0
  327. data/examples/objects/user.rb +20 -0
  328. data/examples/ouadd +38 -0
  329. data/examples/useradd +45 -0
  330. data/examples/useradd-binary +50 -0
  331. data/examples/userdel +34 -0
  332. data/examples/userls +50 -0
  333. data/examples/usermod +42 -0
  334. data/examples/usermod-binary-add +47 -0
  335. data/examples/usermod-binary-add-time +51 -0
  336. data/examples/usermod-binary-del +48 -0
  337. data/examples/usermod-lang-add +43 -0
  338. data/lib/active_ldap/acts/tree.rb +75 -0
  339. data/lib/active_ldap/adapter/base.rb +531 -0
  340. data/lib/active_ldap/adapter/ldap.rb +231 -0
  341. data/lib/active_ldap/adapter/ldap_ext.rb +69 -0
  342. data/lib/active_ldap/adapter/net_ldap.rb +292 -0
  343. data/lib/active_ldap/adapter/net_ldap_ext.rb +29 -0
  344. data/lib/active_ldap/association/belongs_to.rb +47 -0
  345. data/lib/active_ldap/association/belongs_to_many.rb +42 -0
  346. data/lib/active_ldap/association/children.rb +21 -0
  347. data/lib/active_ldap/association/collection.rb +83 -0
  348. data/lib/active_ldap/association/has_many.rb +31 -0
  349. data/lib/active_ldap/association/has_many_utils.rb +35 -0
  350. data/lib/active_ldap/association/has_many_wrap.rb +46 -0
  351. data/lib/active_ldap/association/proxy.rb +102 -0
  352. data/lib/active_ldap/associations.rb +172 -0
  353. data/lib/active_ldap/attributes.rb +211 -0
  354. data/lib/active_ldap/base.rb +1273 -0
  355. data/lib/active_ldap/callbacks.rb +19 -0
  356. data/lib/active_ldap/command.rb +49 -0
  357. data/lib/active_ldap/configuration.rb +147 -0
  358. data/lib/active_ldap/connection.rb +237 -0
  359. data/lib/active_ldap/distinguished_name.rb +251 -0
  360. data/lib/active_ldap/escape.rb +12 -0
  361. data/lib/active_ldap/get_text/parser.rb +159 -0
  362. data/lib/active_ldap/get_text.rb +8 -0
  363. data/lib/active_ldap/get_text_fallback.rb +53 -0
  364. data/lib/active_ldap/get_text_support.rb +26 -0
  365. data/lib/active_ldap/helper.rb +33 -0
  366. data/lib/active_ldap/human_readable.rb +112 -0
  367. data/lib/active_ldap/ldap_error.rb +74 -0
  368. data/lib/active_ldap/ldif.rb +52 -0
  369. data/lib/active_ldap/object_class.rb +93 -0
  370. data/lib/active_ldap/operations.rb +429 -0
  371. data/lib/active_ldap/populate.rb +44 -0
  372. data/lib/active_ldap/schema/syntaxes.rb +386 -0
  373. data/lib/active_ldap/schema.rb +530 -0
  374. data/lib/active_ldap/timeout.rb +75 -0
  375. data/lib/active_ldap/timeout_stub.rb +17 -0
  376. data/lib/active_ldap/user_password.rb +93 -0
  377. data/lib/active_ldap/validations.rb +171 -0
  378. data/lib/active_ldap.rb +982 -0
  379. data/po/en/active-ldap.po +3677 -0
  380. data/po/ja/active-ldap.po +3713 -0
  381. data/rails/plugin/active_ldap/README +54 -0
  382. data/rails/plugin/active_ldap/generators/model_active_ldap/USAGE +17 -0
  383. data/rails/plugin/active_ldap/generators/model_active_ldap/model_active_ldap_generator.rb +70 -0
  384. data/rails/plugin/active_ldap/generators/model_active_ldap/templates/fixtures.yml +11 -0
  385. data/rails/plugin/active_ldap/generators/model_active_ldap/templates/model_active_ldap.rb +3 -0
  386. data/rails/plugin/active_ldap/generators/model_active_ldap/templates/unit_test.rb +10 -0
  387. data/rails/plugin/active_ldap/generators/scaffold_active_ldap/scaffold_active_ldap_generator.rb +7 -0
  388. data/rails/plugin/active_ldap/generators/scaffold_al/scaffold_al_generator.rb +20 -0
  389. data/rails/plugin/active_ldap/init.rb +26 -0
  390. data/test/al-test-utils.rb +362 -0
  391. data/test/command.rb +62 -0
  392. data/test/config.yaml.sample +6 -0
  393. data/test/run-test.rb +31 -0
  394. data/test/test-unit-ext/always-show-result.rb +28 -0
  395. data/test/test-unit-ext/backtrace-filter.rb +17 -0
  396. data/test/test-unit-ext/long-display-for-emacs.rb +25 -0
  397. data/test/test-unit-ext/priority.rb +163 -0
  398. data/test/test-unit-ext.rb +4 -0
  399. data/test/test_acts_as_tree.rb +57 -0
  400. data/test/test_adapter.rb +98 -0
  401. data/test/test_associations.rb +353 -0
  402. data/test/test_attributes.rb +79 -0
  403. data/test/test_base.rb +547 -0
  404. data/test/test_base_per_instance.rb +55 -0
  405. data/test/test_bind.rb +62 -0
  406. data/test/test_callback.rb +35 -0
  407. data/test/test_configuration.rb +40 -0
  408. data/test/test_connection.rb +59 -0
  409. data/test/test_connection_per_class.rb +58 -0
  410. data/test/test_connection_per_dn.rb +78 -0
  411. data/test/test_dn.rb +160 -0
  412. data/test/test_find.rb +96 -0
  413. data/test/test_groupadd.rb +50 -0
  414. data/test/test_groupdel.rb +46 -0
  415. data/test/test_groupls.rb +107 -0
  416. data/test/test_groupmod.rb +51 -0
  417. data/test/test_ldif.rb +35 -0
  418. data/test/test_lpasswd.rb +75 -0
  419. data/test/test_object_class.rb +56 -0
  420. data/test/test_reflection.rb +179 -0
  421. data/test/test_schema.rb +433 -0
  422. data/test/test_syntax.rb +329 -0
  423. data/test/test_user.rb +227 -0
  424. data/test/test_user_password.rb +93 -0
  425. data/test/test_useradd-binary.rb +61 -0
  426. data/test/test_useradd.rb +57 -0
  427. data/test/test_userdel.rb +48 -0
  428. data/test/test_userls.rb +91 -0
  429. data/test/test_usermod-binary-add-time.rb +64 -0
  430. data/test/test_usermod-binary-add.rb +63 -0
  431. data/test/test_usermod-binary-del.rb +66 -0
  432. data/test/test_usermod-lang-add.rb +59 -0
  433. data/test/test_usermod.rb +58 -0
  434. data/test/test_validation.rb +110 -0
  435. metadata +536 -0
@@ -0,0 +1,531 @@
1
+ require 'active_ldap/schema'
2
+ require 'active_ldap/ldap_error'
3
+
4
+ module ActiveLdap
5
+ module Adapter
6
+ class Base
7
+ include GetTextSupport
8
+
9
+ VALID_ADAPTER_CONFIGURATION_KEYS = [:host, :port, :method, :timeout,
10
+ :retry_on_timeout, :retry_limit,
11
+ :retry_wait, :bind_dn, :password,
12
+ :password_block, :try_sasl,
13
+ :sasl_mechanisms, :sasl_quiet,
14
+ :allow_anonymous, :store_password,
15
+ :scope]
16
+ def initialize(configuration={})
17
+ @connection = nil
18
+ @disconnected = false
19
+ @configuration = configuration.dup
20
+ @logger = @configuration.delete(:logger)
21
+ @configuration.assert_valid_keys(VALID_ADAPTER_CONFIGURATION_KEYS)
22
+ VALID_ADAPTER_CONFIGURATION_KEYS.each do |name|
23
+ instance_variable_set("@#{name}", configuration[name])
24
+ end
25
+ end
26
+
27
+ def connect(options={})
28
+ host = options[:host] || @host
29
+ port = options[:port] || @port
30
+ method = ensure_method(options[:method] || @method)
31
+ @disconnected = false
32
+ @connection = yield(host, port, method)
33
+ prepare_connection(options)
34
+ bind(options)
35
+ end
36
+
37
+ def disconnect!(options={})
38
+ return if @connection.nil?
39
+ unbind(options)
40
+ @connection = nil
41
+ end
42
+
43
+ def rebind(options={})
44
+ unbind(options) if bound?
45
+ connect(options)
46
+ end
47
+
48
+ def bind(options={})
49
+ bind_dn = options[:bind_dn] || @bind_dn
50
+ try_sasl = options.has_key?(:try_sasl) ? options[:try_sasl] : @try_sasl
51
+ if options.has_key?(:allow_anonymous)
52
+ allow_anonymous = options[:allow_anonymous]
53
+ else
54
+ allow_anonymous = @allow_anonymous
55
+ end
56
+
57
+ # Rough bind loop:
58
+ # Attempt 1: SASL if available
59
+ # Attempt 2: SIMPLE with credentials if password block
60
+ # Attempt 3: SIMPLE ANONYMOUS if 1 and 2 fail (or pwblock returns '')
61
+ if try_sasl and sasl_bind(bind_dn, options)
62
+ @logger.info {_('Bound by SASL as %s') % bind_dn}
63
+ elsif simple_bind(bind_dn, options)
64
+ @logger.info {_('Bound by simple as %s') % bind_dn}
65
+ elsif allow_anonymous and bind_as_anonymous(options)
66
+ @logger.info {_('Bound as anonymous')}
67
+ else
68
+ message = yield if block_given?
69
+ message ||= _('All authentication methods exhausted.')
70
+ raise AuthenticationError, message
71
+ end
72
+
73
+ bound?
74
+ end
75
+
76
+ def bind_as_anonymous(options={})
77
+ operation(options) do
78
+ yield
79
+ end
80
+ end
81
+
82
+ def connecting?
83
+ !@connection.nil? and !@disconnected
84
+ end
85
+
86
+ def schema(options={})
87
+ @schema ||= operation(options) do
88
+ base = options[:base]
89
+ attrs = options[:attributes]
90
+
91
+ attrs ||= [
92
+ 'objectClasses',
93
+ 'attributeTypes',
94
+ 'matchingRules',
95
+ 'matchingRuleUse',
96
+ 'dITStructureRules',
97
+ 'dITContentRules',
98
+ 'nameForms',
99
+ 'ldapSyntaxes',
100
+ #'extendedAttributeInfo', # if we need RANGE-LOWER/UPPER.
101
+ ]
102
+ base ||= root_dse_values('subschemaSubentry', options)[0]
103
+ base ||= 'cn=schema'
104
+ dn, attributes = search(:base => base,
105
+ :scope => :base,
106
+ :filter => '(objectClass=subschema)',
107
+ :attributes => attrs).first
108
+ Schema.new(attributes)
109
+ end
110
+ end
111
+
112
+ def load(ldifs, options={})
113
+ operation(options) do
114
+ ldifs.split(/(?:\r?\n){2,}/).each do |ldif|
115
+ yield(ldif)
116
+ end
117
+ end
118
+ end
119
+
120
+ def search(options={})
121
+ filter = parse_filter(options[:filter]) || 'objectClass=*'
122
+ attrs = options[:attributes] || []
123
+ scope = ensure_scope(options[:scope] || @scope)
124
+ base = options[:base]
125
+ limit = options[:limit] || 0
126
+ limit = nil if limit <= 0
127
+
128
+ attrs = attrs.to_a # just in case
129
+
130
+ values = []
131
+ callback = Proc.new do |value, block|
132
+ value = block.call(value) if block
133
+ values << value
134
+ end
135
+
136
+ begin
137
+ operation(options) do
138
+ yield(base, scope, filter, attrs, limit, callback)
139
+ end
140
+ rescue LdapError
141
+ # Do nothing on failure
142
+ @logger.info do
143
+ args = [$!.class, $!.message, filter, attrs.inspect]
144
+ _("Ignore error %s(%s): filter %s: attributes: %s") % args
145
+ end
146
+ end
147
+
148
+ values
149
+ end
150
+
151
+ def delete(targets, options={})
152
+ targets = [targets] unless targets.is_a?(Array)
153
+ return if targets.empty?
154
+ target = nil
155
+ begin
156
+ operation(options) do
157
+ targets.each do |target|
158
+ yield(target)
159
+ end
160
+ end
161
+ rescue LdapError::NoSuchObject
162
+ raise EntryNotFound, _("No such entry: %s") % target
163
+ end
164
+ end
165
+
166
+ def add(dn, entries, options={})
167
+ begin
168
+ operation(options) do
169
+ yield(dn, entries)
170
+ end
171
+ rescue LdapError::NoSuchObject
172
+ raise EntryNotFound, _("No such entry: %s") % dn
173
+ rescue LdapError::InvalidDnSyntax
174
+ raise DistinguishedNameInvalid.new(dn)
175
+ rescue LdapError::AlreadyExists
176
+ raise EntryAlreadyExist, _("%s: %s") % [$!.message, dn]
177
+ rescue LdapError::StrongAuthRequired
178
+ raise StrongAuthenticationRequired, _("%s: %s") % [$!.message, dn]
179
+ rescue LdapError::ObjectClassViolation
180
+ raise RequiredAttributeMissed, _("%s: %s") % [$!.message, dn]
181
+ rescue LdapError::UnwillingToPerform
182
+ raise OperationNotPermitted, _("%s: %s") % [$!.message, dn]
183
+ end
184
+ end
185
+
186
+ def modify(dn, entries, options={})
187
+ begin
188
+ operation(options) do
189
+ yield(dn, entries)
190
+ end
191
+ rescue LdapError::UndefinedType
192
+ raise
193
+ rescue LdapError::ObjectClassViolation
194
+ raise RequiredAttributeMissed, _("%s: %s") % [$!.message, dn]
195
+ end
196
+ end
197
+
198
+ private
199
+ def prepare_connection(options)
200
+ end
201
+
202
+ def operation(options)
203
+ retried = false
204
+ begin
205
+ reconnect_if_need
206
+ try_reconnect = !options.has_key?(:try_reconnect) ||
207
+ options[:try_reconnect]
208
+ with_timeout(try_reconnect, options) do
209
+ yield
210
+ end
211
+ rescue Errno::EPIPE
212
+ if retried or !try_reconnect
213
+ raise
214
+ else
215
+ retried = true
216
+ @disconnected = true
217
+ retry
218
+ end
219
+ end
220
+ end
221
+
222
+ def need_credential_sasl_mechanism?(mechanism)
223
+ not %(GSSAPI EXTERNAL ANONYMOUS).include?(mechanism)
224
+ end
225
+
226
+ def password(bind_dn, options={})
227
+ passwd = options[:password] || @password
228
+ return passwd if passwd
229
+
230
+ password_block = options[:password_block] || @password_block
231
+ # TODO: Give a warning to reconnect users with password clearing
232
+ # Get the passphrase for the first time, or anew if we aren't storing
233
+ if password_block.respond_to?(:call)
234
+ passwd = password_block.call(bind_dn)
235
+ else
236
+ @logger.error {_('password_block not nil or Proc object. Ignoring.')}
237
+ return nil
238
+ end
239
+
240
+ # Store the password for quick reference later
241
+ if options.has_key?(:store_password)
242
+ store_password = options[:store_password]
243
+ else
244
+ store_password = @store_password
245
+ end
246
+ @password = store_password ? passwd : nil
247
+
248
+ passwd
249
+ end
250
+
251
+ def with_timeout(try_reconnect=true, options={}, &block)
252
+ begin
253
+ Timeout.alarm(@timeout, &block)
254
+ rescue Timeout::Error => e
255
+ @logger.error {_('Requested action timed out.')}
256
+ retry if try_reconnect and @retry_on_timeout and reconnect(options)
257
+ @logger.error {e.message}
258
+ raise TimeoutError, e.message
259
+ end
260
+ end
261
+
262
+ def sasl_bind(bind_dn, options={})
263
+ return false unless bind_dn
264
+
265
+ # Get all SASL mechanisms
266
+ mechanisms = operation(options) do
267
+ root_dse_values("supportedSASLMechanisms")
268
+ end
269
+
270
+ if options.has_key?(:sasl_quiet)
271
+ sasl_quiet = options[:sasl_quiet]
272
+ else
273
+ sasl_quiet = @sasl_quiet
274
+ end
275
+
276
+ sasl_mechanisms = options[:sasl_mechanisms] || @sasl_mechanisms
277
+ sasl_mechanisms.each do |mechanism|
278
+ next unless mechanisms.include?(mechanism)
279
+ operation(options) do
280
+ yield(bind_dn, mechanism, sasl_quiet)
281
+ return true if bound?
282
+ end
283
+ end
284
+ false
285
+ end
286
+
287
+ def simple_bind(bind_dn, options={})
288
+ return false unless bind_dn
289
+
290
+ passwd = password(bind_dn, options)
291
+ return false unless passwd
292
+
293
+ begin
294
+ operation(options) do
295
+ yield(bind_dn, passwd)
296
+ bound?
297
+ end
298
+ rescue LdapError::InvalidDnSyntax
299
+ raise DistinguishedNameInvalid.new(bind_dn)
300
+ rescue LdapError::InvalidCredentials
301
+ false
302
+ end
303
+ end
304
+
305
+ def parse_filter(filter, operator=nil)
306
+ return nil if filter.nil?
307
+ if !filter.is_a?(String) and !filter.respond_to?(:collect)
308
+ filter = filter.to_s
309
+ end
310
+
311
+ case filter
312
+ when String
313
+ parse_filter_string(filter)
314
+ when Hash
315
+ components = filter.sort_by {|k, v| k.to_s}.collect do |key, value|
316
+ construct_component(key, value, operator)
317
+ end
318
+ construct_filter(components, operator)
319
+ else
320
+ operator, components = normalize_array_filter(filter, operator)
321
+
322
+ components = components.collect do |component|
323
+ if component.is_a?(Array) and component.size == 2
324
+ key, value = component
325
+ if filter_logical_operator?(key)
326
+ parse_filter(component)
327
+ elsif value.is_a?(Hash)
328
+ parse_filter(value, key)
329
+ else
330
+ construct_component(key, value, operator)
331
+ end
332
+ elsif component.is_a?(Symbol)
333
+ assert_filter_logical_operator(component)
334
+ nil
335
+ else
336
+ parse_filter(component, operator)
337
+ end
338
+ end
339
+ construct_filter(components, operator)
340
+ end
341
+ end
342
+
343
+ def parse_filter_string(filter)
344
+ if /\A\s*\z/.match(filter)
345
+ nil
346
+ else
347
+ if filter[0, 1] == "("
348
+ filter
349
+ else
350
+ "(#{filter})"
351
+ end
352
+ end
353
+ end
354
+
355
+ def normalize_array_filter(filter, operator=nil)
356
+ filter_operator, *components = filter
357
+ if filter_logical_operator?(filter_operator)
358
+ operator = filter_operator
359
+ else
360
+ components.unshift(filter_operator)
361
+ end
362
+ [operator, components]
363
+ end
364
+
365
+ def extract_filter_value_options(value)
366
+ options = {}
367
+ if value.is_a?(Array)
368
+ case value[0]
369
+ when Hash
370
+ options = value[0]
371
+ value = value[1]
372
+ when "=", "~=", "<=", "=>"
373
+ options[:operator] = value[1]
374
+ value = value[1]
375
+ end
376
+ end
377
+ [value, options]
378
+ end
379
+
380
+ def construct_component(key, value, operator=nil)
381
+ value, options = extract_filter_value_options(value)
382
+ if collection?(value)
383
+ values = []
384
+ value.each do |val|
385
+ if collection?(val)
386
+ values.concat(val.collect {|v| [key, v]})
387
+ else
388
+ values << [key, val]
389
+ end
390
+ end
391
+ values[0] = values[0][1] if filter_logical_operator?(values[0][1])
392
+ parse_filter(values, operator)
393
+ else
394
+ [
395
+ "(",
396
+ escape_filter_key(key),
397
+ options[:operator] || "=",
398
+ escape_filter_value(value, options),
399
+ ")"
400
+ ].join
401
+ end
402
+ end
403
+
404
+ def escape_filter_key(key)
405
+ escape_filter_value(key.to_s)
406
+ end
407
+
408
+ def escape_filter_value(value, options={})
409
+ case value
410
+ when Numeric, DN
411
+ value = value.to_s
412
+ when Time
413
+ value = Schema::GeneralizedTime.new.normalize_value(value)
414
+ end
415
+ value.gsub(/(?:[()\\\0]|\*\*?)/) do |s|
416
+ if s == "*"
417
+ s
418
+ else
419
+ s = "*" if s == "**"
420
+ "\\%02X" % s[0]
421
+ end
422
+ end
423
+ end
424
+
425
+ def construct_filter(components, operator=nil)
426
+ operator = normalize_filter_logical_operator(operator)
427
+ components = components.compact
428
+ case components.size
429
+ when 0
430
+ nil
431
+ when 1
432
+ filter = components[0]
433
+ filter = "(!#{filter})" if operator == :not
434
+ filter
435
+ else
436
+ "(#{operator == :and ? '&' : '|'}#{components.join})"
437
+ end
438
+ end
439
+
440
+ def collection?(object)
441
+ !object.is_a?(String) and object.respond_to?(:each)
442
+ end
443
+
444
+ LOGICAL_OPERATORS = [:and, :or, :not, :&, :|]
445
+ def filter_logical_operator?(operator)
446
+ LOGICAL_OPERATORS.include?(operator)
447
+ end
448
+
449
+ def normalize_filter_logical_operator(operator)
450
+ assert_filter_logical_operator(operator)
451
+ case (operator || :and)
452
+ when :and, :&
453
+ :and
454
+ when :or, :|
455
+ :or
456
+ else
457
+ :not
458
+ end
459
+ end
460
+
461
+ def assert_filter_logical_operator(operator)
462
+ return if operator.nil?
463
+ unless filter_logical_operator?(operator)
464
+ raise ArgumentError,
465
+ _("invalid logical operator: %s: available operators: %s") %
466
+ [operator.inspect, LOGICAL_OPERATORS.inspect]
467
+ end
468
+ end
469
+
470
+ # Attempts to reconnect up to the number of times allowed
471
+ # If forced, try once then fail with ConnectionError if not connected.
472
+ def reconnect(options={})
473
+ options = options.dup
474
+ force = options[:force]
475
+ retry_limit = options[:retry_limit] || @retry_limit
476
+ retry_wait = options[:retry_wait] || @retry_wait
477
+ options[:reconnect_attempts] ||= 0
478
+
479
+ loop do
480
+ unless can_reconnect?(options)
481
+ raise ConnectionError,
482
+ _('Giving up trying to reconnect to LDAP server.')
483
+ end
484
+
485
+ @logger.debug {_('Attempting to reconnect')}
486
+ disconnect!
487
+
488
+ # Reset the attempts if this was forced.
489
+ options[:reconnect_attempts] = 0 if force
490
+ options[:reconnect_attempts] += 1 if retry_limit >= 0
491
+ begin
492
+ connect(options)
493
+ break
494
+ rescue => detail
495
+ @logger.error do
496
+ _("Reconnect to server failed: %s\n" \
497
+ "Reconnect to server failed backtrace:\n" \
498
+ "%s") % [detail.exception, detail.backtrace.join("\n")]
499
+ end
500
+ # Do not loop if forced
501
+ raise ConnectionError, detail.message if force
502
+ end
503
+
504
+ # Sleep before looping
505
+ sleep retry_wait
506
+ end
507
+
508
+ true
509
+ end
510
+
511
+ def reconnect_if_need(options={})
512
+ reconnect(options) if !connecting? and can_reconnect?(options)
513
+ end
514
+
515
+ # Determine if we have exceed the retry limit or not.
516
+ # True is reconnecting is allowed - False if not.
517
+ def can_reconnect?(options={})
518
+ retry_limit = options[:retry_limit] || @retry_limit
519
+ reconnect_attempts = options[:reconnect_attempts] || 0
520
+
521
+ retry_limit < 0 or reconnect_attempts < (retry_limit - 1)
522
+ end
523
+
524
+ def root_dse_values(key, options={})
525
+ dse = root_dse([key], options)[0]
526
+ return [] if dse.nil?
527
+ dse[key] || dse[key.downcase] || []
528
+ end
529
+ end
530
+ end
531
+ end