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,231 @@
1
+ require 'active_ldap/adapter/base'
2
+
3
+ module ActiveLdap
4
+ module Adapter
5
+ class Base
6
+ class << self
7
+ def ldap_connection(options)
8
+ require 'active_ldap/adapter/ldap_ext'
9
+ Ldap.new(options)
10
+ end
11
+ end
12
+ end
13
+
14
+ class Ldap < Base
15
+ module Method
16
+ class SSL
17
+ def connect(host, port)
18
+ LDAP::SSLConn.new(host, port, false)
19
+ end
20
+ end
21
+
22
+ class TLS
23
+ def connect(host, port)
24
+ LDAP::SSLConn.new(host, port, true)
25
+ end
26
+ end
27
+
28
+ class Plain
29
+ def connect(host, port)
30
+ LDAP::Conn.new(host, port)
31
+ end
32
+ end
33
+ end
34
+
35
+ def connect(options={})
36
+ super do |host, port, method|
37
+ method.connect(host, port)
38
+ end
39
+ end
40
+
41
+ def unbind(options={})
42
+ return unless bound?
43
+ operation(options) do
44
+ execute(:unbind)
45
+ end
46
+ end
47
+
48
+ def bind(options={})
49
+ super do
50
+ @connection.error_message
51
+ end
52
+ end
53
+
54
+ def bind_as_anonymous(options={})
55
+ super do
56
+ execute(:bind)
57
+ true
58
+ end
59
+ end
60
+
61
+ def bound?
62
+ connecting? and @connection.bound?
63
+ end
64
+
65
+ def search(options={}, &block)
66
+ super(options) do |base, scope, filter, attrs, limit, callback|
67
+ begin
68
+ i = 0
69
+ execute(:search, base, scope, filter, attrs) do |entry|
70
+ i += 1
71
+ attributes = {}
72
+ entry.attrs.each do |attr|
73
+ attributes[attr] = entry.vals(attr)
74
+ end
75
+ callback.call([entry.dn, attributes], block)
76
+ break if limit and limit <= i
77
+ end
78
+ rescue RuntimeError
79
+ if $!.message == "no result returned by search"
80
+ @logger.debug do
81
+ args = [filter, attrs.inspect]
82
+ _("No matches: filter: %s: attributes: %s") % args
83
+ end
84
+ else
85
+ raise
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ def to_ldif(dn, attributes)
92
+ ldif = LDAP::LDIF.to_ldif("dn", [dn.dup])
93
+ attributes.sort_by do |key, value|
94
+ key
95
+ end.each do |key, values|
96
+ ldif << LDAP::LDIF.to_ldif(key, values)
97
+ end
98
+ ldif
99
+ end
100
+
101
+ def load(ldifs, options={})
102
+ super do |ldif|
103
+ LDAP::LDIF.parse_entry(ldif).send(@connection)
104
+ end
105
+ end
106
+
107
+ def delete(targets, options={})
108
+ super do |target|
109
+ execute(:delete, target)
110
+ end
111
+ end
112
+
113
+ def add(dn, entries, options={})
114
+ super do |dn, entries|
115
+ execute(:add, dn, parse_entries(entries))
116
+ end
117
+ end
118
+
119
+ def modify(dn, entries, options={})
120
+ super do |dn, entries|
121
+ execute(:modify, dn, parse_entries(entries))
122
+ end
123
+ end
124
+
125
+ private
126
+ def prepare_connection(options={})
127
+ operation(options) do
128
+ @connection.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
129
+ end
130
+ end
131
+
132
+ def root_dse(attributes, options={})
133
+ sec = options[:sec] || 0
134
+ usec = options[:usec] || 0
135
+ @connection.root_dse(attributes, sec, usec)
136
+ end
137
+
138
+ def execute(method, *args, &block)
139
+ begin
140
+ @connection.send(method, *args, &block)
141
+ rescue LDAP::ResultError
142
+ @connection.assert_error_code
143
+ raise $!.message
144
+ end
145
+ end
146
+
147
+ def with_timeout(try_reconnect=true, options={}, &block)
148
+ begin
149
+ super
150
+ rescue LDAP::ServerDown => e
151
+ @logger.error {_("LDAP server is down: %s") % e.message}
152
+ retry if try_reconnect and reconnect(options)
153
+ raise ConnectionError.new(e.message)
154
+ end
155
+ end
156
+
157
+ def ensure_method(method)
158
+ Method.constants.each do |name|
159
+ if method.to_s.downcase == name.downcase
160
+ return Method.const_get(name).new
161
+ end
162
+ end
163
+
164
+ available_methods = Method.constants.collect do |name|
165
+ name.downcase.to_sym.inspect
166
+ end.join(", ")
167
+ format = _("%s is not one of the available connect methods: %s")
168
+ raise ConfigurationError, format % [method.inspect, available_methods]
169
+ end
170
+
171
+ def ensure_scope(scope)
172
+ scope_map = {
173
+ :base => LDAP::LDAP_SCOPE_BASE,
174
+ :sub => LDAP::LDAP_SCOPE_SUBTREE,
175
+ :one => LDAP::LDAP_SCOPE_ONELEVEL,
176
+ }
177
+ value = scope_map[scope || :sub]
178
+ if value.nil?
179
+ available_scopes = scope_map.keys.inspect
180
+ format = _("%s is not one of the available LDAP scope: %s")
181
+ raise ArgumentError, format % [scope.inspect, available_scopes]
182
+ end
183
+ value
184
+ end
185
+
186
+ def sasl_bind(bind_dn, options={})
187
+ super do |bind_dn, mechanism, quiet|
188
+ begin
189
+ sasl_quiet = @connection.sasl_quiet
190
+ @connection.sasl_quiet = quiet unless quiet.nil?
191
+ args = [bind_dn, mechanism]
192
+ if need_credential_sasl_mechanism?(mechanism)
193
+ args << password(bind_dn, options)
194
+ end
195
+ execute(:sasl_bind, *args)
196
+ ensure
197
+ @connection.sasl_quiet = sasl_quiet
198
+ end
199
+ end
200
+ end
201
+
202
+ def simple_bind(bind_dn, options={})
203
+ super do |bind_dn, passwd|
204
+ execute(:bind, bind_dn, passwd)
205
+ end
206
+ end
207
+
208
+ def parse_entries(entries)
209
+ result = []
210
+ entries.each do |type, key, attributes|
211
+ mod_type = ensure_mod_type(type)
212
+ binary = schema.attribute(key).binary?
213
+ mod_type |= LDAP::LDAP_MOD_BVALUES if binary
214
+ attributes.each do |name, values|
215
+ result << LDAP.mod(mod_type, name, values)
216
+ end
217
+ end
218
+ result
219
+ end
220
+
221
+ def ensure_mod_type(type)
222
+ case type
223
+ when :replace, :add
224
+ LDAP.const_get("LDAP_MOD_#{type.to_s.upcase}")
225
+ else
226
+ raise ArgumentError, _("unknown type: %s") % type
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,69 @@
1
+ require 'ldap'
2
+ require 'ldap/ldif'
3
+ require 'ldap/schema'
4
+
5
+ module LDAP
6
+ class Mod
7
+ unless instance_method(:to_s).arity.zero?
8
+ alias_method :original_to_s, :to_s
9
+ def to_s
10
+ inspect
11
+ end
12
+ end
13
+
14
+ alias_method :_initialize, :initialize
15
+ def initialize(op, type, vals)
16
+ if (VERSION.split(/\./).collect {|x| x.to_i} <=> [0, 9, 7]) <= 0
17
+ @op, @type, @vals = op, type, vals # to protect from GC
18
+ end
19
+ _initialize(op, type, vals)
20
+ end
21
+ end
22
+
23
+ IMPLEMENT_SPECIFIC_ERRORS = {}
24
+ {
25
+ 0x51 => "SERVER_DOWN",
26
+ 0x52 => "LOCAL_ERROR",
27
+ 0x53 => "ENCODING_ERROR",
28
+ 0x54 => "DECODING_ERROR",
29
+ 0x55 => "TIMEOUT",
30
+ 0x56 => "AUTH_UNKNOWN",
31
+ 0x57 => "FILTER_ERROR",
32
+ 0x58 => "USER_CANCELLED",
33
+ 0x59 => "PARAM_ERROR",
34
+ 0x5a => "NO_MEMORY",
35
+
36
+ 0x5b => "CONNECT_ERROR",
37
+ 0x5c => "NOT_SUPPORTED",
38
+ 0x5d => "CONTROL_NOT_FOUND",
39
+ 0x5e => "NO_RESULTS_RETURNED",
40
+ 0x5f => "MORE_RESULTS_TO_RETURN",
41
+ 0x60 => "CLIENT_LOOP",
42
+ 0x61 => "REFERRAL_LIMIT_EXCEEDED",
43
+ }.each do |code, name|
44
+ IMPLEMENT_SPECIFIC_ERRORS[code] =
45
+ ActiveLdap::LdapError.define(code, name, self)
46
+ end
47
+
48
+ class Conn
49
+ def failed?
50
+ not err.zero?
51
+ end
52
+
53
+ def error_message
54
+ if failed?
55
+ LDAP.err2string(err)
56
+ else
57
+ nil
58
+ end
59
+ end
60
+
61
+ def assert_error_code
62
+ return unless failed?
63
+ klass = ActiveLdap::LdapError::ERRORS[err]
64
+ klass ||= IMPLEMENT_SPECIFIC_ERRORS[err]
65
+ klass ||= ActiveLdap::LdapError
66
+ raise klass, LDAP.err2string(err)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,292 @@
1
+ require 'digest/md5'
2
+
3
+ require 'active_ldap/adapter/base'
4
+
5
+ module ActiveLdap
6
+ module Adapter
7
+ class Base
8
+ class << self
9
+ def net_ldap_connection(options)
10
+ require 'active_ldap/adapter/net_ldap_ext'
11
+ NetLdap.new(options)
12
+ end
13
+ end
14
+ end
15
+
16
+ class NetLdap < Base
17
+ METHOD = {
18
+ :ssl => :simple_tls,
19
+ :tls => :start_tls,
20
+ :plain => nil,
21
+ }
22
+
23
+ def connect(options={})
24
+ @bound = false
25
+ super do |host, port, method|
26
+ config = {
27
+ :host => host,
28
+ :port => port,
29
+ }
30
+ config[:encryption] = {:method => method} if method
31
+ begin
32
+ Net::LDAP::Connection.new(config)
33
+ rescue Net::LDAP::LdapError
34
+ raise ConnectionError, $!.message
35
+ end
36
+ end
37
+ end
38
+
39
+ def unbind(options={})
40
+ @bound = false
41
+ end
42
+
43
+ def bind(options={})
44
+ @bound = false
45
+ begin
46
+ super
47
+ rescue Net::LDAP::LdapError
48
+ raise AuthenticationError, $!.message
49
+ end
50
+ end
51
+
52
+ def bind_as_anonymous(options={})
53
+ super do
54
+ @bound = false
55
+ execute(:bind, :method => :anonymous)
56
+ @bound = true
57
+ end
58
+ end
59
+
60
+ def bound?
61
+ connecting? and @bound
62
+ end
63
+
64
+ def search(options={}, &block)
65
+ super(options) do |base, scope, filter, attrs, limit, callback|
66
+ args = {
67
+ :base => base,
68
+ :scope => scope,
69
+ :filter => filter,
70
+ :attributes => attrs,
71
+ :size => limit,
72
+ }
73
+ execute(:search, args) do |entry|
74
+ attributes = {}
75
+ entry.original_attribute_names.each do |name|
76
+ attributes[name] = entry[name]
77
+ end
78
+ callback.call([entry.dn, attributes], block)
79
+ end
80
+ end
81
+ end
82
+
83
+ def to_ldif(dn, attributes)
84
+ entry = Net::LDAP::Entry.new(dn.dup)
85
+ attributes.each do |key, values|
86
+ entry[key] = values.flatten
87
+ end
88
+ entry.to_ldif
89
+ end
90
+
91
+ def load(ldifs, options={})
92
+ super do |ldif|
93
+ entry = Net::LDAP::Entry.from_single_ldif_string(ldif)
94
+ attributes = {}
95
+ entry.each do |name, values|
96
+ attributes[name] = values
97
+ end
98
+ attributes.delete(:dn)
99
+ execute(:add,
100
+ :dn => entry.dn,
101
+ :attributes => attributes)
102
+ end
103
+ end
104
+
105
+ def delete(targets, options={})
106
+ super do |target|
107
+ execute(:delete, :dn => target)
108
+ end
109
+ end
110
+
111
+ def add(dn, entries, options={})
112
+ super do |dn, entries|
113
+ attributes = {}
114
+ entries.each do |type, key, attrs|
115
+ attrs.each do |name, values|
116
+ attributes[name] = values
117
+ end
118
+ end
119
+ execute(:add, :dn => dn, :attributes => attributes)
120
+ end
121
+ end
122
+
123
+ def modify(dn, entries, options={})
124
+ super do |dn, entries|
125
+ execute(:modify,
126
+ :dn => dn,
127
+ :operations => parse_entries(entries))
128
+ end
129
+ end
130
+
131
+ private
132
+ def execute(method, *args, &block)
133
+ result = @connection.send(method, *args, &block)
134
+ message = nil
135
+ if result.is_a?(Hash)
136
+ message = result[:errorMessage]
137
+ result = result[:resultCode]
138
+ end
139
+ unless result.zero?
140
+ klass = LdapError::ERRORS[result]
141
+ klass ||= LdapError
142
+ raise klass,
143
+ [Net::LDAP.result2string(result), message].compact.join(": ")
144
+ end
145
+ end
146
+
147
+ def root_dse(attrs, options={})
148
+ search(:base => "",
149
+ :scope => :base,
150
+ :attributes => attrs).collect do |dn, attributes|
151
+ attributes
152
+ end
153
+ end
154
+
155
+ def ensure_method(method)
156
+ method ||= "plain"
157
+ normalized_method = method.to_s.downcase.to_sym
158
+ return METHOD[normalized_method] if METHOD.has_key?(normalized_method)
159
+
160
+ available_methods = METHOD.keys.collect {|m| m.inspect}.join(", ")
161
+ format = _("%s is not one of the available connect methods: %s")
162
+ raise ConfigurationError, format % [method.inspect, available_methods]
163
+ end
164
+
165
+ def ensure_scope(scope)
166
+ scope_map = {
167
+ :base => Net::LDAP::SearchScope_BaseObject,
168
+ :sub => Net::LDAP::SearchScope_WholeSubtree,
169
+ :one => Net::LDAP::SearchScope_SingleLevel,
170
+ }
171
+ value = scope_map[scope || :sub]
172
+ if value.nil?
173
+ available_scopes = scope_map.keys.inspect
174
+ format = _("%s is not one of the available LDAP scope: %s")
175
+ raise ArgumentError, format % [scope.inspect, available_scopes]
176
+ end
177
+ value
178
+ end
179
+
180
+ def sasl_bind(bind_dn, options={})
181
+ super do |bind_dn, mechanism, quiet|
182
+ normalized_mechanism = mechanism.downcase.gsub(/-/, '_')
183
+ sasl_bind_setup = "sasl_bind_setup_#{normalized_mechanism}"
184
+ next unless respond_to?(sasl_bind_setup, true)
185
+ initial_credential, challenge_response =
186
+ send(sasl_bind_setup, bind_dn, options)
187
+ args = {
188
+ :method => :sasl,
189
+ :initial_credential => initial_credential,
190
+ :mechanism => mechanism,
191
+ :challenge_response => challenge_response,
192
+ }
193
+ @bound = false
194
+ execute(:bind, args)
195
+ @bound = true
196
+ end
197
+ end
198
+
199
+ def sasl_bind_setup_digest_md5(bind_dn, options)
200
+ initial_credential = ""
201
+ nonce_count = 1
202
+ challenge_response = Proc.new do |cred|
203
+ params = parse_sasl_digest_md5_credential(cred)
204
+ qops = params["qop"].split(/,/)
205
+ unless qops.include?("auth")
206
+ raise ActiveLdap::AuthenticationError,
207
+ _("unsupported qops: %s") % qops.inspect
208
+ end
209
+ qop = "auth"
210
+ server = @connection.instance_variable_get("@conn").addr[2]
211
+ realm = params['realm']
212
+ uri = "ldap/#{server}"
213
+ nc = "%08x" % nonce_count
214
+ nonce = params["nonce"]
215
+ cnonce = generate_client_nonce
216
+ requests = {
217
+ :username => bind_dn.inspect,
218
+ :realm => realm.inspect,
219
+ :nonce => nonce.inspect,
220
+ :cnonce => cnonce.inspect,
221
+ :nc => nc,
222
+ :qop => qop,
223
+ :maxbuf => "65536",
224
+ "digest-uri" => uri.inspect,
225
+ }
226
+ a1 = "#{bind_dn}:#{realm}:#{password(cred, options)}"
227
+ a1 = "#{Digest::MD5.digest(a1)}:#{nonce}:#{cnonce}"
228
+ ha1 = Digest::MD5.hexdigest(a1)
229
+ a2 = "AUTHENTICATE:#{uri}"
230
+ ha2 = Digest::MD5.hexdigest(a2)
231
+ response = "#{ha1}:#{nonce}:#{nc}:#{cnonce}:#{qop}:#{ha2}"
232
+ requests["response"] = Digest::MD5.hexdigest(response)
233
+ nonce_count += 1
234
+ requests.collect do |key, value|
235
+ "#{key}=#{value}"
236
+ end.join(",")
237
+ end
238
+ [initial_credential, challenge_response]
239
+ end
240
+
241
+ def parse_sasl_digest_md5_credential(cred)
242
+ params = {}
243
+ cred.scan(/(\w+)=(\"?)(.+?)\2(?:,|$)/) do |name, sep, value|
244
+ params[name] = value
245
+ end
246
+ params
247
+ end
248
+
249
+ CHARS = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
250
+ def generate_client_nonce(size=32)
251
+ nonce = ""
252
+ size.times do |i|
253
+ nonce << CHARS[rand(CHARS.size)]
254
+ end
255
+ nonce
256
+ end
257
+
258
+ def simple_bind(bind_dn, options={})
259
+ super do |bind_dn, passwd|
260
+ args = {
261
+ :method => :simple,
262
+ :username => bind_dn,
263
+ :password => passwd,
264
+ }
265
+ @bound = false
266
+ execute(:bind, args)
267
+ @bound = true
268
+ end
269
+ end
270
+
271
+ def parse_entries(entries)
272
+ result = []
273
+ entries.each do |type, key, attributes|
274
+ mod_type = ensure_mod_type(type)
275
+ attributes.each do |name, values|
276
+ result << [mod_type, name, values]
277
+ end
278
+ end
279
+ result
280
+ end
281
+
282
+ def ensure_mod_type(type)
283
+ case type
284
+ when :replace, :add
285
+ type
286
+ else
287
+ raise ArgumentError, _("unknown type: %s") % type
288
+ end
289
+ end
290
+ end
291
+ end
292
+ end
@@ -0,0 +1,29 @@
1
+ require_library_or_gem 'net/ldap'
2
+
3
+ module Net
4
+ class LDAP
5
+ class Entry
6
+ alias initialize_without_original_attribute_names initialize
7
+ def initialize(*args)
8
+ @original_attribute_names = []
9
+ initialize_without_original_attribute_names(*args)
10
+ end
11
+
12
+ alias aset_without_original_attribute_names []=
13
+ def []=(name, value)
14
+ @original_attribute_names << name
15
+ aset_without_original_attribute_names(name, value)
16
+ end
17
+
18
+ def original_attribute_names
19
+ @original_attribute_names.compact.uniq
20
+ end
21
+
22
+ def each_attribute
23
+ attribute_names.sort_by {|name| name.to_s}.each do |name|
24
+ yield name, self[name]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,47 @@
1
+ require 'active_ldap/association/proxy'
2
+
3
+ module ActiveLdap
4
+ module Association
5
+ class BelongsTo < Proxy
6
+ def replace(entry)
7
+ if entry.nil?
8
+ @target = @owner[@options[:foreign_key_name]] = nil
9
+ else
10
+ @target = (Proxy === entry ? entry.target : entry)
11
+ infect_connection(@target)
12
+ unless entry.new_entry?
13
+ @owner[@options[:foreign_key_name]] = entry[primary_key]
14
+ end
15
+ @updated = true
16
+ end
17
+
18
+ loaded
19
+ entry
20
+ end
21
+
22
+ def updated?
23
+ @updated
24
+ end
25
+
26
+ private
27
+ def have_foreign_key?
28
+ not @owner[@options[:foreign_key_name]].nil?
29
+ end
30
+
31
+ def find_target
32
+ value = @owner[@options[:foreign_key_name]]
33
+ raise EntryNotFound if value.nil?
34
+ key = primary_key
35
+ if key == "dn"
36
+ result = foreign_class.find(value, find_options)
37
+ else
38
+ filter = {key => value}
39
+ options = find_options(:filter => filter, :limit => 1)
40
+ result = foreign_class.find(:all, options).first
41
+ end
42
+ raise EntryNotFound if result.nil?
43
+ result
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,42 @@
1
+ require 'active_ldap/association/collection'
2
+
3
+ module ActiveLdap
4
+ module Association
5
+ class BelongsToMany < Collection
6
+ private
7
+ def insert_entry(entry)
8
+ old_value = entry[@options[:many], true]
9
+ new_value = old_value + @owner[@options[:foreign_key_name], true]
10
+ new_value = new_value.uniq.sort
11
+ if old_value != new_value
12
+ entry[@options[:many]] = new_value
13
+ entry.save
14
+ end
15
+ end
16
+
17
+ def delete_entries(entries)
18
+ entries.each do |entry|
19
+ old_value = entry[@options[:many], true]
20
+ new_value = old_value - @owner[@options[:foreign_key_name], true]
21
+ new_value = new_value.uniq.sort
22
+ if old_value != new_value
23
+ entry[@options[:many]] = new_value
24
+ entry.save
25
+ end
26
+ end
27
+ end
28
+
29
+ def find_target
30
+ values = @owner[@options[:foreign_key_name], true].compact
31
+ return [] if values.empty?
32
+
33
+ key = @options[:many]
34
+ components = values.collect do |value|
35
+ [key, value]
36
+ end
37
+ options = find_options(:filter => [:or, *components])
38
+ foreign_class.find(:all, options)
39
+ end
40
+ end
41
+ end
42
+ end