activeldap3 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
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,51 @@
1
+ require 'al-test-utils'
2
+
3
+ class TestGroupmod < Test::Unit::TestCase
4
+ include AlTestUtils
5
+
6
+ def setup
7
+ super
8
+ @command = File.join(@examples_dir, "groupmod")
9
+ end
10
+
11
+ priority :must
12
+
13
+ priority :normal
14
+ def test_non_exist_group
15
+ ensure_delete_group("test-group") do |name|
16
+ assert(!@group_class.exists?(name))
17
+ assert_equal([false, "Group #{name} doesn't exist.\n"],
18
+ run_command(name, 111111))
19
+ assert(!@group_class.exists?(name))
20
+ end
21
+ end
22
+
23
+ def test_modify_group
24
+ make_temporary_group do |group|
25
+ assert_groupmod_successfully(group.cn, group.gid_number.succ)
26
+ end
27
+ end
28
+
29
+ private
30
+ def assert_groupmod_successfully(name, gid, *args, &block)
31
+ _wrap_assertion do
32
+ assert(@group_class.exists?(name))
33
+ args.concat([name, gid])
34
+ assert_equal([true, ""], run_command(*args, &block))
35
+ assert(@group_class.exists?(name))
36
+
37
+ group = @group_class.find(name)
38
+ assert_equal(name, group.cn)
39
+ assert_equal(gid, group.gid_number)
40
+ end
41
+ end
42
+
43
+ def assert_groupmod_failed(name, gid, message, *args, &block)
44
+ _wrap_assertion do
45
+ assert(@group_class.exists?(name))
46
+ args.concat([name, gid])
47
+ assert_equal([false, message], run_command(*args, &block))
48
+ assert(@group_class.exists?(name))
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,1891 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'al-test-utils'
4
+
5
+ class TestLDIF < Test::Unit::TestCase
6
+ include ActiveLdap::GetTextSupport
7
+ include AlTestUtils::Assertions
8
+ include AlTestUtils::Config
9
+ include AlTestUtils::ExampleFile
10
+
11
+ priority :must
12
+ def test_integer_attribute_value_to_s
13
+ dn = ActiveLdap::DN.parse("uid=user,ou=People,dc=example,dc=com")
14
+ record = ActiveLdap::Ldif::Record.new(dn, {"uidNumber" => [100]})
15
+ assert_equal(<<-EOL, record.to_s)
16
+ dn: uid=user,ou=People,dc=example,dc=com
17
+ uidNumber: 100
18
+ EOL
19
+ end
20
+
21
+ priority :normal
22
+ def test_accept_empty_lines_after_content
23
+ ldif_source = <<-EOL
24
+ version: 1
25
+ dn: dc=devel,dc=example,dc=com
26
+ dc: devel
27
+ objectClass: top
28
+ objectClass: dcObject
29
+ objectClass: organization
30
+ o: devel
31
+ EOL
32
+
33
+ expected_ldif_to_s = <<-EOL
34
+ version: 1
35
+ dn: dc=devel,dc=example,dc=com
36
+ dc: devel
37
+ o: devel
38
+ objectClass: dcObject
39
+ objectClass: organization
40
+ objectClass: top
41
+ EOL
42
+
43
+
44
+ assert_ldif_to_s(expected_ldif_to_s, ldif_source)
45
+ assert_ldif_to_s(expected_ldif_to_s, ldif_source + "\n")
46
+ assert_ldif_to_s(expected_ldif_to_s, ldif_source + "\n\n")
47
+ assert_ldif_to_s(expected_ldif_to_s, ldif_source + ("\n" * 10))
48
+ end
49
+
50
+ def test_accept_comments_after_content
51
+ ldif_source = <<-EOL
52
+ version: 1
53
+ dn: dc=devel,dc=example,dc=com
54
+ dc: devel
55
+ objectClass: top
56
+ objectClass: dcObject
57
+ objectClass: organization
58
+ o: devel
59
+
60
+ # search result
61
+
62
+ # numResponse: 1
63
+ # numEntries: 1
64
+
65
+ EOL
66
+
67
+ assert_ldif_to_s(<<-EOL, ldif_source)
68
+ version: 1
69
+ dn: dc=devel,dc=example,dc=com
70
+ dc: devel
71
+ o: devel
72
+ objectClass: dcObject
73
+ objectClass: organization
74
+ objectClass: top
75
+ EOL
76
+ end
77
+
78
+ def test_comments_and_empty_lines_before_content
79
+ ldif_source = <<-EOL
80
+ version: 1
81
+
82
+ #
83
+ # LDAPv3
84
+ # base <dc=devel,dc=clear-code,dc=com> with scope subtree
85
+ # filter: (objectclass=*)
86
+ # requesting: ALL
87
+ #
88
+
89
+ # devel.example.com
90
+ dn: dc=devel,dc=example,dc=com
91
+ dc: devel
92
+ objectClass: top
93
+ objectClass: dcObject
94
+ objectClass: organization
95
+ o: devel
96
+ EOL
97
+
98
+ assert_ldif_to_s(<<-EOL, ldif_source)
99
+ version: 1
100
+ dn: dc=devel,dc=example,dc=com
101
+ dc: devel
102
+ o: devel
103
+ objectClass: dcObject
104
+ objectClass: organization
105
+ objectClass: top
106
+ EOL
107
+ end
108
+
109
+ def test_unknown_change_type
110
+ ldif_source = <<-EOL
111
+ version: 1
112
+ dn: ou=Product Development, dc=airius, dc=com
113
+ changetype: XXX
114
+ EOL
115
+
116
+ ldif_source_with_error_mark = <<-EOL
117
+ changetype: |@|XXX
118
+ EOL
119
+
120
+ assert_invalid_ldif(["unknown change type: %s", "XXX"],
121
+ ldif_source, 3, 13, ldif_source_with_error_mark)
122
+ end
123
+
124
+ def test_unknown_modify_type
125
+ ldif_source = <<-EOL
126
+ version: 1
127
+ dn: ou=Product Development, dc=airius, dc=com
128
+ changetype: modify
129
+ XXX: postaladdress
130
+ -
131
+ EOL
132
+
133
+ ldif_source_with_error_mark = <<-EOL
134
+ |@|XXX: postaladdress
135
+ EOL
136
+
137
+ assert_invalid_ldif(["unknown modify type: %s", "XXX"],
138
+ ldif_source, 4, 1, ldif_source_with_error_mark)
139
+ end
140
+
141
+ def test_modify_spec_block_separator_is_missing
142
+ ldif_source = <<-EOL
143
+ version: 1
144
+ dn: ou=Product Development, dc=airius, dc=com
145
+ changetype: modify
146
+ add: postaladdress
147
+ EOL
148
+
149
+ ldif_source_with_error_mark = <<-EOL.chomp
150
+ add: postaladdress
151
+ |@|
152
+ EOL
153
+
154
+ assert_invalid_ldif("'-' is missing",
155
+ ldif_source, 5, 1, ldif_source_with_error_mark)
156
+ end
157
+
158
+ def test_modify_spec_first_line_separator_is_missing
159
+ ldif_source = <<-EOL.chomp
160
+ version: 1
161
+ dn: ou=Product Development, dc=airius, dc=com
162
+ changetype: modify
163
+ add: postaladdress
164
+ EOL
165
+
166
+ ldif_source_with_error_mark = <<-EOL.chomp
167
+ add: postaladdress|@|
168
+ EOL
169
+
170
+ assert_invalid_ldif("separator is missing",
171
+ ldif_source, 4, 19, ldif_source_with_error_mark)
172
+ end
173
+
174
+ def test_modify_target_attribute_name_is_missing
175
+ ldif_source = <<-EOL
176
+ version: 1
177
+ dn: ou=Product Development, dc=airius, dc=com
178
+ changetype: modify
179
+ add:
180
+ -
181
+ EOL
182
+
183
+ ldif_source_with_error_mark = <<-EOL
184
+ add:|@|
185
+ EOL
186
+
187
+ assert_invalid_ldif("attribute type is missing",
188
+ ldif_source, 4, 5, ldif_source_with_error_mark)
189
+ end
190
+
191
+ def test_newsuperior_separator_is_missing
192
+ ldif_source = <<-EOL.chomp
193
+ version: 1
194
+ dn: ou=Product Development, dc=airius, dc=com
195
+ changetype: moddn
196
+ newrdn: cn=Paula Jensen
197
+ deleteoldrdn: 1
198
+ newsuperior: ou=Accounting, dc=airius, dc=com
199
+ EOL
200
+
201
+ ldif_source_with_error_mark = <<-EOL.chomp
202
+ newsuperior: ou=Accounting, dc=airius, dc=com|@|
203
+ EOL
204
+
205
+ assert_invalid_ldif("separator is missing",
206
+ ldif_source, 6, 46, ldif_source_with_error_mark)
207
+ end
208
+
209
+ def test_newsuperior_value_is_missing
210
+ ldif_source = <<-EOL
211
+ version: 1
212
+ dn: ou=Product Development, dc=airius, dc=com
213
+ changetype: moddn
214
+ newrdn: cn=Paula Jensen
215
+ deleteoldrdn: 1
216
+ newsuperior:
217
+ EOL
218
+
219
+ ldif_source_with_error_mark = <<-EOL
220
+ newsuperior:|@|
221
+ EOL
222
+
223
+ assert_invalid_ldif("new superior value is missing",
224
+ ldif_source, 6, 13, ldif_source_with_error_mark)
225
+ end
226
+
227
+ def test_deleteoldrdn_separator_is_missing
228
+ ldif_source = <<-EOL.chomp
229
+ version: 1
230
+ dn: ou=Product Development, dc=airius, dc=com
231
+ changetype: moddn
232
+ newrdn: cn=Paula Jensen
233
+ deleteoldrdn: 1
234
+ EOL
235
+
236
+ ldif_source_with_error_mark = <<-EOL.chomp
237
+ deleteoldrdn: 1|@|
238
+ EOL
239
+
240
+ assert_invalid_ldif("separator is missing",
241
+ ldif_source, 5, 16, ldif_source_with_error_mark)
242
+ end
243
+
244
+ def test_invalid_deleteoldrdn_value
245
+ ldif_source = <<-EOL
246
+ version: 1
247
+ dn: ou=Product Development, dc=airius, dc=com
248
+ changetype: moddn
249
+ newrdn: cn=Paula Jensen
250
+ deleteoldrdn: x
251
+ EOL
252
+
253
+ ldif_source_with_error_mark = <<-EOL
254
+ deleteoldrdn: |@|x
255
+ EOL
256
+
257
+ assert_invalid_ldif("delete old RDN value is missing",
258
+ ldif_source, 5, 15, ldif_source_with_error_mark)
259
+ end
260
+
261
+ def test_deleteoldrdn_value_is_missing
262
+ ldif_source = <<-EOL
263
+ version: 1
264
+ dn: ou=Product Development, dc=airius, dc=com
265
+ changetype: moddn
266
+ newrdn: cn=Paula Jensen
267
+ deleteoldrdn:
268
+ EOL
269
+
270
+ ldif_source_with_error_mark = <<-EOL
271
+ deleteoldrdn:|@|
272
+ EOL
273
+
274
+ assert_invalid_ldif("delete old RDN value is missing",
275
+ ldif_source, 5, 14, ldif_source_with_error_mark)
276
+ end
277
+
278
+ def test_deleteoldrdn_mark_is_missing
279
+ ldif_source = <<-EOL
280
+ version: 1
281
+ dn: ou=Product Development, dc=airius, dc=com
282
+ changetype: moddn
283
+ newrdn: cn=Paula Jensen
284
+ EOL
285
+
286
+ ldif_source_with_error_mark = <<-EOL.chomp
287
+ newrdn: cn=Paula Jensen
288
+ |@|
289
+ EOL
290
+
291
+ assert_invalid_ldif("'deleteoldrdn:' is missing",
292
+ ldif_source, 5, 1, ldif_source_with_error_mark)
293
+ end
294
+
295
+ def test_newrdn_separator_is_missing
296
+ ldif_source = <<-EOL.chomp
297
+ version: 1
298
+ dn: ou=Product Development, dc=airius, dc=com
299
+ changetype: moddn
300
+ newrdn: cn=Paula Jensen
301
+ EOL
302
+
303
+ ldif_source_with_error_mark = <<-EOL.chomp
304
+ newrdn: cn=Paula Jensen|@|
305
+ EOL
306
+
307
+ assert_invalid_ldif("separator is missing",
308
+ ldif_source, 4, 24, ldif_source_with_error_mark)
309
+ end
310
+
311
+ def test_newrdn_value_is_missing
312
+ ldif_source = <<-EOL
313
+ version: 1
314
+ dn: ou=Product Development, dc=airius, dc=com
315
+ changetype: moddn
316
+ newrdn:
317
+ EOL
318
+
319
+ ldif_source_with_error_mark = <<-EOL
320
+ newrdn:|@|
321
+ EOL
322
+
323
+ assert_invalid_ldif("new RDN value is missing",
324
+ ldif_source, 4, 8, ldif_source_with_error_mark)
325
+ end
326
+
327
+ def test_newrdn_mark_is_missing
328
+ ldif_source = <<-EOL
329
+ version: 1
330
+ dn: ou=Product Development, dc=airius, dc=com
331
+ changetype: moddn
332
+ EOL
333
+
334
+ ldif_source_with_error_mark = <<-EOL.chomp
335
+ changetype: moddn
336
+ |@|
337
+ EOL
338
+
339
+ assert_invalid_ldif("'newrdn:' is missing",
340
+ ldif_source, 4, 1, ldif_source_with_error_mark)
341
+ end
342
+
343
+ def test_add_change_type_without_attribute
344
+ ldif_source = <<-EOL
345
+ version: 1
346
+ dn: ou=Product Development, dc=airius, dc=com
347
+ changetype: add
348
+ EOL
349
+
350
+ ldif_source_with_error_mark = <<-EOL.chomp
351
+ changetype: add
352
+ |@|
353
+ EOL
354
+
355
+ assert_invalid_ldif("attribute spec is missing",
356
+ ldif_source, 4, 1, ldif_source_with_error_mark)
357
+ end
358
+
359
+ def test_change_type_with_an_extra_space
360
+ ldif_source = <<-EOL
361
+ version: 1
362
+ dn: ou=Product Development, dc=airius, dc=com
363
+ changetype: delete
364
+ EOL
365
+
366
+ ldif_source_with_error_mark = <<-EOL
367
+ changetype: delete|@|
368
+ EOL
369
+
370
+ assert_invalid_ldif("separator is missing",
371
+ ldif_source, 3, 19, ldif_source_with_error_mark)
372
+ end
373
+
374
+ def test_change_type_separator_is_missing
375
+ ldif_source = <<-EOL.chomp
376
+ version: 1
377
+ dn: ou=Product Development, dc=airius, dc=com
378
+ changetype: delete
379
+ EOL
380
+
381
+ ldif_source_with_error_mark = <<-EOL.chomp
382
+ changetype: delete|@|
383
+ EOL
384
+
385
+ assert_invalid_ldif("separator is missing",
386
+ ldif_source, 3, 19, ldif_source_with_error_mark)
387
+ end
388
+
389
+ def test_change_type_value_is_missing
390
+ ldif_source = <<-EOL
391
+ version: 1
392
+ dn: ou=Product Development, dc=airius, dc=com
393
+ changetype:
394
+ EOL
395
+
396
+ ldif_source_with_error_mark = <<-EOL
397
+ changetype:|@|
398
+ EOL
399
+
400
+ assert_invalid_ldif("change type value is missing",
401
+ ldif_source, 3, 12, ldif_source_with_error_mark)
402
+ end
403
+
404
+ def test_control_separator_is_missing
405
+ ldif_source = <<-EOL.chomp
406
+ version: 1
407
+ dn: ou=Product Development, dc=airius, dc=com
408
+ control: 1.2.840.113556.1.4.805 true
409
+ EOL
410
+
411
+ ldif_source_with_error_mark = <<-EOL.chomp
412
+ control: 1.2.840.113556.1.4.805 true|@|
413
+ EOL
414
+
415
+ assert_invalid_ldif("separator is missing",
416
+ ldif_source, 3, 37, ldif_source_with_error_mark)
417
+ end
418
+
419
+ def test_criticality_is_missing
420
+ ldif_source = <<-EOL
421
+ version: 1
422
+ dn: ou=Product Development, dc=airius, dc=com
423
+ control: 1.2.840.113556.1.4.805
424
+ EOL
425
+
426
+ ldif_source_with_error_mark = <<-EOL
427
+ control: 1.2.840.113556.1.4.805 |@|
428
+ EOL
429
+
430
+ assert_invalid_ldif("criticality is missing",
431
+ ldif_source, 3, 33, ldif_source_with_error_mark)
432
+ end
433
+
434
+ def test_control_type_is_missing
435
+ ldif_source = <<-EOL
436
+ version: 1
437
+ dn: ou=Product Development, dc=airius, dc=com
438
+ control:
439
+ EOL
440
+
441
+ ldif_source_with_error_mark = <<-EOL
442
+ control:|@|
443
+ EOL
444
+
445
+ assert_invalid_ldif("control type is missing",
446
+ ldif_source, 3, 9, ldif_source_with_error_mark)
447
+ end
448
+
449
+ def test_change_type_is_missing
450
+ ldif_source = <<-EOL
451
+ version: 1
452
+ dn: ou=Product Development, dc=airius, dc=com
453
+ control: 1.2.840.113556.1.4.805 true
454
+ EOL
455
+
456
+ ldif_source_with_error_mark = <<-EOL.chomp
457
+ control: 1.2.840.113556.1.4.805 true
458
+ |@|
459
+ EOL
460
+
461
+ assert_invalid_ldif("change type is missing",
462
+ ldif_source, 4, 1, ldif_source_with_error_mark)
463
+ end
464
+
465
+ def test_invalid_dn
466
+ ldif_source = <<-EOL
467
+ version: 1
468
+ dn: ou=o=Airius
469
+ EOL
470
+
471
+ ldif_source_with_error_mark = <<-EOL
472
+ dn: ou=o=Airius|@|
473
+ EOL
474
+
475
+ assert_invalid_ldif(["DN is invalid: %s: %s",
476
+ "ou=o=Airius", "attribute type is missing"],
477
+ ldif_source, 2, 16, ldif_source_with_error_mark)
478
+ end
479
+
480
+ def test_invalid_dn_value
481
+ ldif_source = <<-EOL
482
+ version: 1
483
+ # dn:: ou=<JapaneseOU>,o=Airius
484
+ dn: ou=営業部,o=Airius
485
+ EOL
486
+
487
+ ldif_source_with_error_mark = <<-EOL
488
+ dn: ou=|@|営業部,o=Airius
489
+ EOL
490
+
491
+ assert_invalid_ldif(["DN has an invalid character: %s", "営"],
492
+ ldif_source, 3, 8, ldif_source_with_error_mark)
493
+ end
494
+
495
+ def test_multi_records_without_separator
496
+ ldif_source = <<-EOL
497
+ version: 1
498
+ dn: ou=Product Development, dc=airius, dc=com
499
+ changetype: delete
500
+ dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com
501
+ seealso:
502
+ description::
503
+ EOL
504
+
505
+ ldif_source_with_error_mark = <<-EOL
506
+ |@|dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com
507
+ EOL
508
+
509
+ assert_invalid_ldif("separator is missing", ldif_source,
510
+ 4, 1, ldif_source_with_error_mark)
511
+ end
512
+
513
+ def test_to_s_with_blank_value
514
+ ldif_source = <<-EOL
515
+ version: 1
516
+ dn: ou=Product Development,dc=airius,dc=com
517
+ seealso:
518
+ description::
519
+ EOL
520
+
521
+ assert_ldif_to_s(<<-EOL, ldif_source)
522
+ version: 1
523
+ dn: ou=Product Development,dc=airius,dc=com
524
+ description:
525
+ seealso:
526
+ EOL
527
+ end
528
+
529
+ def test_to_s_with_last_space
530
+ ldif_source = <<-EOL
531
+ version: 1
532
+ # 'ou=Product Development,dc=airius,dc=com '
533
+ dn:: b3U9UHJvZHVjdCBEZXZlbG9wbWVudCwgZGM9YWlyaXVzLCBkYz1jb20g
534
+ # 'ou=Product Development,dc=airius,dc=com '
535
+ description:: b3U9UHJvZHVjdCBEZXZlbG9wbWVudCwgZGM9YWlyaXVzLCBkYz1jb20g
536
+ EOL
537
+
538
+ assert_ldif_to_s(<<-EOL, ldif_source)
539
+ version: 1
540
+ dn: ou=Product Development,dc=airius,dc="com "
541
+ description:: b3U9UHJvZHVjdCBEZXZlbG9wbWVudCwgZGM9YWlyaXVzLCBkYz1jb20g
542
+ EOL
543
+ end
544
+
545
+ def test_change_record_with_control
546
+ ldif_source = <<-EOL
547
+ version: 1
548
+ # Delete an entry. The operation will attach the LDAPv3
549
+ # Tree Delete Control defined in [9]. The criticality
550
+ # field is "true" and the controlValue field is
551
+ # absent, as required by [9].
552
+ dn: ou=Product Development, dc=airius, dc=com
553
+ control: 1.2.840.113556.1.4.805 true
554
+ changetype: delete
555
+ EOL
556
+
557
+ change_attributes = {
558
+ "dn" => "ou=Product Development,dc=airius,dc=com",
559
+ }
560
+
561
+ ldif = assert_ldif(1, [change_attributes], ldif_source)
562
+ record = ldif.records[0]
563
+ assert_equal("delete", record.change_type)
564
+ assert_true(record.delete?)
565
+ assert_equal([{
566
+ :type => "1.2.840.113556.1.4.805",
567
+ :criticality => true,
568
+ :value => nil
569
+ }],
570
+ record.controls.collect {|control| control.to_hash})
571
+
572
+ control = record.controls[0]
573
+ assert_equal("1.2.840.113556.1.4.805", control.type)
574
+ assert_true(control.criticality?)
575
+ assert_nil(control.value)
576
+ end
577
+
578
+ def test_change_record_with_control_to_s
579
+ ldif_source = <<-EOL
580
+ version: 1
581
+ # Delete an entry. The operation will attach the LDAPv3
582
+ # Tree Delete Control defined in [9]. The criticality
583
+ # field is "true" and the controlValue field is
584
+ # absent, as required by [9].
585
+ dn: ou=Product Development, dc=airius, dc=com
586
+ control: 1.2.840.113556.1.4.805 true
587
+ changetype: delete
588
+ EOL
589
+
590
+ assert_ldif_to_s(<<-EOL, ldif_source)
591
+ version: 1
592
+ dn: ou=Product Development,dc=airius,dc=com
593
+ control: 1.2.840.113556.1.4.805 true
594
+ changetype: delete
595
+ EOL
596
+ end
597
+
598
+ def test_multi_change_type_records
599
+ ldif_source = <<-EOL
600
+ version: 1
601
+ # Add a new entry
602
+ dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com
603
+ changetype: add
604
+ objectclass: top
605
+ objectclass: person
606
+ objectclass: organizationalPerson
607
+ cn: Fiona Jensen
608
+ sn: Jensen
609
+ uid: fiona
610
+ telephonenumber: +1 408 555 1212
611
+
612
+ # Delete an existing entry
613
+ dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com
614
+ changetype: delete
615
+
616
+ # Modify an entry's relative distinguished name
617
+ dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com
618
+ changetype: modrdn
619
+ newrdn: cn=Paula Jensen
620
+ deleteoldrdn: 1
621
+
622
+ # Rename an entry and move all of its children to a new location in
623
+ # the directory tree (only implemented by LDAPv3 servers).
624
+ dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com
625
+ changetype: modrdn
626
+ newrdn: ou=Product Development Accountants
627
+ deleteoldrdn: 0
628
+ newsuperior: ou=Accounting, dc=airius, dc=com
629
+
630
+ # Modify an entry: add an additional value to the postaladdress
631
+ # attribute, completely delete the description attribute, replace
632
+ # the telephonenumber attribute with two values, and delete a specific
633
+ # value from the facsimiletelephonenumber attribute
634
+ dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com
635
+ changetype: modify
636
+ add: postaladdress
637
+ postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086
638
+ -
639
+ delete: description
640
+ -
641
+ replace: telephonenumber
642
+ telephonenumber: +1 408 555 1234
643
+ telephonenumber: +1 408 555 5678
644
+ -
645
+ delete: facsimiletelephonenumber
646
+ facsimiletelephonenumber: +1 408 555 9876
647
+ -
648
+
649
+ # Modify an entry: replace the postaladdress attribute with an empty
650
+ # set of values (which will cause the attribute to be removed), and
651
+ # delete the entire description attribute. Note that the first will
652
+ # always succeed, while the second will only succeed if at least
653
+ # one value for the description attribute is present.
654
+ dn: cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com
655
+ changetype: modify
656
+ replace: postaladdress
657
+ -
658
+ delete: description
659
+ -
660
+ EOL
661
+
662
+ assert_ldif_to_s(<<-EOL, ldif_source)
663
+ version: 1
664
+ dn: cn=Fiona Jensen,ou=Marketing,dc=airius,dc=com
665
+ changetype: add
666
+ cn: Fiona Jensen
667
+ objectclass: organizationalPerson
668
+ objectclass: person
669
+ objectclass: top
670
+ sn: Jensen
671
+ telephonenumber: +1 408 555 1212
672
+ uid: fiona
673
+
674
+ dn: cn=Robert Jensen,ou=Marketing,dc=airius,dc=com
675
+ changetype: delete
676
+
677
+ dn: cn=Paul Jensen,ou=Product Development,dc=airius,dc=com
678
+ changetype: modrdn
679
+ newrdn: cn=Paula Jensen
680
+ deleteoldrdn: 1
681
+
682
+ dn: ou=PD Accountants,ou=Product Development,dc=airius,dc=com
683
+ changetype: modrdn
684
+ newrdn: ou=Product Development Accountants
685
+ deleteoldrdn: 0
686
+ newsuperior: ou=Accounting,dc=airius,dc=com
687
+
688
+ dn: cn=Paula Jensen,ou=Product Development,dc=airius,dc=com
689
+ changetype: modify
690
+ add: postaladdress
691
+ postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086
692
+ -
693
+ delete: description
694
+ -
695
+ replace: telephonenumber
696
+ telephonenumber: +1 408 555 1234
697
+ telephonenumber: +1 408 555 5678
698
+ -
699
+ delete: facsimiletelephonenumber
700
+ facsimiletelephonenumber: +1 408 555 9876
701
+ -
702
+
703
+ dn: cn=Ingrid Jensen,ou=Product Support,dc=airius,dc=com
704
+ changetype: modify
705
+ replace: postaladdress
706
+ -
707
+ delete: description
708
+ -
709
+ EOL
710
+
711
+ change_attributes_add = {
712
+ "dn" => "cn=Fiona Jensen,ou=Marketing,dc=airius,dc=com",
713
+ "objectclass" => ["top", "person", "organizationalPerson"],
714
+ "cn" => ["Fiona Jensen"],
715
+ "sn" => ["Jensen"],
716
+ "uid" => ["fiona"],
717
+ "telephonenumber" => ["+1 408 555 1212"],
718
+ }
719
+
720
+ change_attributes_delete = {
721
+ "dn" => "cn=Robert Jensen,ou=Marketing,dc=airius,dc=com",
722
+ }
723
+
724
+ change_attributes_modrdn = {
725
+ "dn" => "cn=Paul Jensen,ou=Product Development,dc=airius,dc=com",
726
+ }
727
+
728
+ change_attributes_modrdn_with_new_superior = {
729
+ "dn" => "ou=PD Accountants,ou=Product Development,dc=airius,dc=com",
730
+ }
731
+
732
+ change_attributes_modify = {
733
+ "dn" => "cn=Paula Jensen,ou=Product Development,dc=airius,dc=com",
734
+ }
735
+
736
+ change_attributes_modify_with_empty_replace = {
737
+ "dn" => "cn=Ingrid Jensen,ou=Product Support,dc=airius,dc=com",
738
+ }
739
+
740
+ ldif = assert_ldif(1,
741
+ [change_attributes_add,
742
+ change_attributes_delete,
743
+ change_attributes_modrdn,
744
+ change_attributes_modrdn_with_new_superior,
745
+ change_attributes_modify,
746
+ change_attributes_modify_with_empty_replace],
747
+ ldif_source)
748
+ record = ldif.records[0]
749
+ assert_equal("add", record.change_type)
750
+ assert_true(record.add?)
751
+
752
+ record = ldif.records[1]
753
+ assert_equal("delete", record.change_type)
754
+ assert_true(record.delete?)
755
+
756
+ record = ldif.records[2]
757
+ assert_equal("modrdn", record.change_type)
758
+ assert_true(record.modify_rdn?)
759
+ assert_equal("cn=Paula Jensen", record.new_rdn)
760
+ assert_true(record.delete_old_rdn?)
761
+ assert_nil(record.new_superior)
762
+
763
+ record = ldif.records[3]
764
+ assert_equal("modrdn", record.change_type)
765
+ assert_true(record.modify_rdn?)
766
+ assert_equal("ou=Product Development Accountants", record.new_rdn)
767
+ assert_false(record.delete_old_rdn?)
768
+ assert_equal("ou=Accounting,dc=airius,dc=com", record.new_superior)
769
+
770
+ record = ldif.records[4]
771
+ assert_equal("modify", record.change_type)
772
+ assert_true(record.modify?)
773
+ operations = [
774
+ ["add", "postaladdress",
775
+ {"postaladdress" =>
776
+ ["123 Anystreet $ Sunnyvale, CA $ 94086"]}],
777
+ ["delete", "description", {}],
778
+ ["replace", "telephonenumber",
779
+ {"telephonenumber" => [
780
+ "+1 408 555 1234",
781
+ "+1 408 555 5678",
782
+ ]}],
783
+ ["delete", "facsimiletelephonenumber",
784
+ {"facsimiletelephonenumber" => ["+1 408 555 9876"]}],
785
+ ]
786
+ i = -1
787
+ actual = record.operations.collect do |operation|
788
+ i += 1
789
+ type = operations[i][0]
790
+ [operation.send("#{type}?"),
791
+ [operation.type, operation.attribute, operation.attributes]]
792
+ end
793
+ assert_equal(operations.collect {|operation| [true, operation]},
794
+ actual)
795
+
796
+ record = ldif.records[5]
797
+ assert_equal("modify", record.change_type)
798
+ assert_true(record.modify?)
799
+ operations = [
800
+ ["replace", "postaladdress", {}],
801
+ ["delete", "description", {}],
802
+ ]
803
+ i = -1
804
+ actual = record.operations.collect do |operation|
805
+ i += 1
806
+ type = operations[i][0]
807
+ [operation.send("#{type}?"),
808
+ [operation.type, operation.attribute, operation.attributes]]
809
+ end
810
+ assert_equal(operations.collect {|operation| [true, operation]},
811
+ actual)
812
+ end
813
+
814
+ def test_modify_record
815
+ ldif_source = <<-EOL
816
+ version: 1
817
+ # Modify an entry: add an additional value to the postaladdress
818
+ # attribute, completely delete the description attribute, replace
819
+ # the telephonenumber attribute with two values, and delete a specific
820
+ # value from the facsimiletelephonenumber attribute
821
+ dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com
822
+ changetype: modify
823
+ add: postaladdress
824
+ postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086
825
+ -
826
+ delete: description
827
+ -
828
+ replace: telephonenumber
829
+ telephonenumber: +1 408 555 1234
830
+ telephonenumber: +1 408 555 5678
831
+ -
832
+ delete: facsimiletelephonenumber
833
+ facsimiletelephonenumber: +1 408 555 9876
834
+ -
835
+ EOL
836
+
837
+ change_attributes = {
838
+ "dn" => "cn=Paula Jensen,ou=Product Development,dc=airius,dc=com",
839
+ }
840
+
841
+ ldif = assert_ldif(1, [change_attributes], ldif_source)
842
+ record = ldif.records[0]
843
+ assert_equal("modify", record.change_type)
844
+ assert_true(record.modify?)
845
+
846
+ operations = [
847
+ ["add", "postaladdress",
848
+ {"postaladdress" =>
849
+ ["123 Anystreet $ Sunnyvale, CA $ 94086"]}],
850
+ ["delete", "description", {}],
851
+ ["replace", "telephonenumber",
852
+ {"telephonenumber" => [
853
+ "+1 408 555 1234",
854
+ "+1 408 555 5678",
855
+ ]}],
856
+ ["delete", "facsimiletelephonenumber",
857
+ {"facsimiletelephonenumber" => ["+1 408 555 9876"]}],
858
+ ]
859
+ i = -1
860
+ actual = record.operations.collect do |operation|
861
+ i += 1
862
+ type = operations[i][0]
863
+ [operation.send("#{type}?"),
864
+ [operation.type, operation.attribute, operation.attributes]]
865
+ end
866
+ assert_equal(operations.collect {|operation| [true, operation]},
867
+ actual)
868
+ end
869
+
870
+ def test_modify_record_to_s
871
+ ldif_source = <<-EOL
872
+ version: 1
873
+ # Modify an entry: add an additional value to the postaladdress
874
+ # attribute, completely delete the description attribute, replace
875
+ # the telephonenumber attribute with two values, and delete a specific
876
+ # value from the facsimiletelephonenumber attribute
877
+ dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com
878
+ changetype: modify
879
+ add: postaladdress
880
+ postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086
881
+ -
882
+ delete: description
883
+ -
884
+ replace: telephonenumber
885
+ telephonenumber: +1 408 555 1234
886
+ telephonenumber: +1 408 555 5678
887
+ -
888
+ delete: facsimiletelephonenumber
889
+ facsimiletelephonenumber: +1 408 555 9876
890
+ -
891
+ EOL
892
+
893
+ assert_ldif_to_s(<<-EOL, ldif_source)
894
+ version: 1
895
+ dn: cn=Paula Jensen,ou=Product Development,dc=airius,dc=com
896
+ changetype: modify
897
+ add: postaladdress
898
+ postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086
899
+ -
900
+ delete: description
901
+ -
902
+ replace: telephonenumber
903
+ telephonenumber: +1 408 555 1234
904
+ telephonenumber: +1 408 555 5678
905
+ -
906
+ delete: facsimiletelephonenumber
907
+ facsimiletelephonenumber: +1 408 555 9876
908
+ -
909
+ EOL
910
+ end
911
+
912
+ def test_modrdn_record_with_newsuperior
913
+ ldif_source = <<-EOL
914
+ version: 1
915
+ # Rename an entry and move all of its children to a new location in
916
+ # the directory tree (only implemented by LDAPv3 servers).
917
+ dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com
918
+ changetype: modrdn
919
+ newrdn: ou=Product Development Accountants
920
+ deleteoldrdn: 0
921
+ newsuperior: ou=Accounting, dc=airius, dc=com
922
+ EOL
923
+
924
+ change_attributes = {
925
+ "dn" => "ou=PD Accountants,ou=Product Development,dc=airius,dc=com",
926
+ }
927
+
928
+ ldif = assert_ldif(1, [change_attributes], ldif_source)
929
+ record = ldif.records[0]
930
+ assert_equal("modrdn", record.change_type)
931
+ assert_true(record.modify_rdn?)
932
+ assert_equal("ou=Product Development Accountants", record.new_rdn)
933
+ assert_false(record.delete_old_rdn?)
934
+ assert_equal("ou=Accounting,dc=airius,dc=com", record.new_superior)
935
+ end
936
+
937
+ def test_modrdn_record_with_newsuperior_to_s
938
+ ldif_source = <<-EOL
939
+ version: 1
940
+ # Rename an entry and move all of its children to a new location in
941
+ # the directory tree (only implemented by LDAPv3 servers).
942
+ dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com
943
+ changetype: modrdn
944
+ newrdn: ou=Product Development Accountants
945
+ deleteoldrdn: 0
946
+ newsuperior: ou=Accounting, dc=airius, dc=com
947
+ EOL
948
+
949
+ assert_ldif_to_s(<<-EOL, ldif_source)
950
+ version: 1
951
+ dn: ou=PD Accountants,ou=Product Development,dc=airius,dc=com
952
+ changetype: modrdn
953
+ newrdn: ou=Product Development Accountants
954
+ deleteoldrdn: 0
955
+ newsuperior: ou=Accounting,dc=airius,dc=com
956
+ EOL
957
+ end
958
+
959
+ def test_modrdn_record
960
+ ldif_source = <<-EOL
961
+ version: 1
962
+ # Modify an entry's relative distinguished name
963
+ dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com
964
+ changetype: modrdn
965
+ newrdn: cn=Paula Jensen
966
+ deleteoldrdn: 1
967
+ EOL
968
+
969
+ change_attributes = {
970
+ "dn" => "cn=Paul Jensen,ou=Product Development,dc=airius,dc=com",
971
+ }
972
+
973
+ ldif = assert_ldif(1, [change_attributes], ldif_source)
974
+ record = ldif.records[0]
975
+ assert_equal("modrdn", record.change_type)
976
+ assert_true(record.modify_rdn?)
977
+ assert_equal("cn=Paula Jensen", record.new_rdn)
978
+ assert_true(record.delete_old_rdn?)
979
+ assert_nil(record.new_superior)
980
+ end
981
+
982
+ def test_modrdn_record_to_s
983
+ ldif_source = <<-EOL
984
+ version: 1
985
+ # Modify an entry's relative distinguished name
986
+ dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com
987
+ changetype: modrdn
988
+ newrdn: cn=Paula Jensen
989
+ deleteoldrdn: 1
990
+ EOL
991
+
992
+ assert_ldif_to_s(<<-EOL, ldif_source)
993
+ version: 1
994
+ dn: cn=Paul Jensen,ou=Product Development,dc=airius,dc=com
995
+ changetype: modrdn
996
+ newrdn: cn=Paula Jensen
997
+ deleteoldrdn: 1
998
+ EOL
999
+ end
1000
+
1001
+ def test_moddn_record_with_newsuperior
1002
+ ldif_source = <<-EOL
1003
+ version: 1
1004
+ # Rename an entry and move all of its children to a new location in
1005
+ # the directory tree (only implemented by LDAPv3 servers).
1006
+ dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com
1007
+ changetype: moddn
1008
+ newrdn: ou=Product Development Accountants
1009
+ deleteoldrdn: 0
1010
+ newsuperior: ou=Accounting, dc=airius, dc=com
1011
+ EOL
1012
+
1013
+ change_attributes = {
1014
+ "dn" => "ou=PD Accountants,ou=Product Development,dc=airius,dc=com",
1015
+ }
1016
+
1017
+ ldif = assert_ldif(1, [change_attributes], ldif_source)
1018
+ record = ldif.records[0]
1019
+ assert_equal("moddn", record.change_type)
1020
+ assert_true(record.modify_dn?)
1021
+ assert_equal("ou=Product Development Accountants", record.new_rdn)
1022
+ assert_false(record.delete_old_rdn?)
1023
+ assert_equal("ou=Accounting,dc=airius,dc=com", record.new_superior)
1024
+ end
1025
+
1026
+ def test_moddn_record_with_newsuperior_to_s
1027
+ ldif_source = <<-EOL
1028
+ version: 1
1029
+ # Rename an entry and move all of its children to a new location in
1030
+ # the directory tree (only implemented by LDAPv3 servers).
1031
+ dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com
1032
+ changetype: moddn
1033
+ newrdn: ou=Product Development Accountants
1034
+ deleteoldrdn: 0
1035
+ newsuperior: ou=Accounting, dc=airius, dc=com
1036
+ EOL
1037
+
1038
+ assert_ldif_to_s(<<-EOL, ldif_source)
1039
+ version: 1
1040
+ dn: ou=PD Accountants,ou=Product Development,dc=airius,dc=com
1041
+ changetype: moddn
1042
+ newrdn: ou=Product Development Accountants
1043
+ deleteoldrdn: 0
1044
+ newsuperior: ou=Accounting,dc=airius,dc=com
1045
+ EOL
1046
+ end
1047
+
1048
+ def test_moddn_record
1049
+ ldif_source = <<-EOL
1050
+ version: 1
1051
+ # Modify an entry's relative distinguished name
1052
+ dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com
1053
+ changetype: moddn
1054
+ newrdn: cn=Paula Jensen
1055
+ deleteoldrdn: 1
1056
+ EOL
1057
+
1058
+ change_attributes = {
1059
+ "dn" => "cn=Paul Jensen,ou=Product Development,dc=airius,dc=com",
1060
+ }
1061
+
1062
+ ldif = assert_ldif(1, [change_attributes], ldif_source)
1063
+ record = ldif.records[0]
1064
+ assert_equal("moddn", record.change_type)
1065
+ assert_true(record.modify_dn?)
1066
+ assert_equal("cn=Paula Jensen", record.new_rdn)
1067
+ assert_true(record.delete_old_rdn?)
1068
+ assert_nil(record.new_superior)
1069
+ end
1070
+
1071
+ def test_moddn_record_to_s
1072
+ ldif_source = <<-EOL
1073
+ version: 1
1074
+ # Modify an entry's relative distinguished name
1075
+ dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com
1076
+ changetype: moddn
1077
+ newrdn: cn=Paula Jensen
1078
+ deleteoldrdn: 1
1079
+ EOL
1080
+
1081
+ assert_ldif_to_s(<<-EOL, ldif_source)
1082
+ version: 1
1083
+ dn: cn=Paul Jensen,ou=Product Development,dc=airius,dc=com
1084
+ changetype: moddn
1085
+ newrdn: cn=Paula Jensen
1086
+ deleteoldrdn: 1
1087
+ EOL
1088
+ end
1089
+
1090
+ def test_delete_record
1091
+ ldif_source = <<-EOL
1092
+ version: 1
1093
+ # Delete an existing entry
1094
+ dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com
1095
+ changetype: delete
1096
+ EOL
1097
+
1098
+ change_attributes = {
1099
+ "dn" => "cn=Robert Jensen,ou=Marketing,dc=airius,dc=com",
1100
+ }
1101
+
1102
+ ldif = assert_ldif(1, [change_attributes], ldif_source)
1103
+ record = ldif.records[0]
1104
+ assert_equal("delete", record.change_type)
1105
+ assert_true(record.delete?)
1106
+ end
1107
+
1108
+ def test_delete_record_to_s
1109
+ ldif_source = <<-EOL
1110
+ version: 1
1111
+ # Delete an existing entry
1112
+ dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com
1113
+ changetype: delete
1114
+ EOL
1115
+
1116
+ assert_ldif_to_s(<<-EOL, ldif_source)
1117
+ version: 1
1118
+ dn: cn=Robert Jensen,ou=Marketing,dc=airius,dc=com
1119
+ changetype: delete
1120
+ EOL
1121
+ end
1122
+
1123
+ def test_add_record
1124
+ ldif_source = <<-EOL
1125
+ version: 1
1126
+ # Add a new entry
1127
+ dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com
1128
+ changetype: add
1129
+ objectclass: top
1130
+ objectclass: person
1131
+ objectclass: organizationalPerson
1132
+ cn: Fiona Jensen
1133
+ sn: Jensen
1134
+ uid: fiona
1135
+ telephonenumber: +1 408 555 1212
1136
+ EOL
1137
+
1138
+ change_attributes = {
1139
+ "dn" => "cn=Fiona Jensen,ou=Marketing,dc=airius,dc=com",
1140
+ "objectclass" => ["top", "person", "organizationalPerson"],
1141
+ "cn" => ["Fiona Jensen"],
1142
+ "sn" => ["Jensen"],
1143
+ "uid" => ["fiona"],
1144
+ "telephonenumber" => ["+1 408 555 1212"],
1145
+ }
1146
+
1147
+ ldif = assert_ldif(1, [change_attributes], ldif_source)
1148
+ record = ldif.records[0]
1149
+ assert_equal("add", record.change_type)
1150
+ assert_true(record.add?)
1151
+ end
1152
+
1153
+ def test_add_record_to_s
1154
+ ldif_source = <<-EOL
1155
+ version: 1
1156
+ # Add a new entry
1157
+ dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com
1158
+ changetype: add
1159
+ objectclass: top
1160
+ objectclass: person
1161
+ objectclass: organizationalPerson
1162
+ cn: Fiona Jensen
1163
+ sn: Jensen
1164
+ uid: fiona
1165
+ telephonenumber: +1 408 555 1212
1166
+ EOL
1167
+
1168
+ assert_ldif_to_s(<<-EOL, ldif_source)
1169
+ version: 1
1170
+ dn: cn=Fiona Jensen,ou=Marketing,dc=airius,dc=com
1171
+ changetype: add
1172
+ cn: Fiona Jensen
1173
+ objectclass: organizationalPerson
1174
+ objectclass: person
1175
+ objectclass: top
1176
+ sn: Jensen
1177
+ telephonenumber: +1 408 555 1212
1178
+ uid: fiona
1179
+ EOL
1180
+ end
1181
+
1182
+ def test_records_with_external_file_reference
1183
+ ldif_source = <<-EOL
1184
+ version: 1
1185
+ dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com
1186
+ objectclass: top
1187
+ objectclass: person
1188
+ objectclass: organizationalPerson
1189
+ cn: Horatio Jensen
1190
+ cn: Horatio N Jensen
1191
+ sn: Jensen
1192
+ uid: hjensen
1193
+ telephonenumber: +1 408 555 1212
1194
+ jpegphoto:< file://#{jpeg_photo_path}
1195
+ EOL
1196
+
1197
+ record = {
1198
+ "dn" => "cn=Horatio Jensen,ou=Product Testing,dc=airius,dc=com",
1199
+ "objectclass" => ["top", "person", "organizationalPerson"],
1200
+ "cn" => ["Horatio Jensen", "Horatio N Jensen"],
1201
+ "sn" => ["Jensen"],
1202
+ "uid" => ["hjensen"],
1203
+ "telephonenumber" => ["+1 408 555 1212"],
1204
+ "jpegphoto" => [jpeg_photo],
1205
+ }
1206
+
1207
+ assert_ldif(1, [record], ldif_source)
1208
+ end
1209
+
1210
+ def test_records_with_external_file_reference_to_s
1211
+ ldif_source = <<-EOL
1212
+ version: 1
1213
+ dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com
1214
+ objectclass: top
1215
+ objectclass: person
1216
+ objectclass: organizationalPerson
1217
+ cn: Horatio Jensen
1218
+ cn: Horatio N Jensen
1219
+ sn: Jensen
1220
+ uid: hjensen
1221
+ telephonenumber: +1 408 555 1212
1222
+ jpegphoto:< file://#{jpeg_photo_path}
1223
+ EOL
1224
+ set_encoding(ldif_source, "utf-8")
1225
+
1226
+ jpeg_photo_attribute = "jpegphoto:: "
1227
+ value = [jpeg_photo].pack("m").gsub(/\n/, '')
1228
+ first_line_value_size = 75 - jpeg_photo_attribute.size
1229
+ jpeg_photo_attribute << value[0, first_line_value_size] + "\n"
1230
+ value = value[first_line_value_size..-1]
1231
+ value.scan(/.{1,74}/).each do |line|
1232
+ jpeg_photo_attribute << " #{line}\n"
1233
+ end
1234
+ jpeg_photo_attribute = jpeg_photo_attribute.chomp
1235
+
1236
+ assert_ldif_to_s(<<-EOL, ldif_source)
1237
+ version: 1
1238
+ dn: cn=Horatio Jensen,ou=Product Testing,dc=airius,dc=com
1239
+ cn: Horatio Jensen
1240
+ cn: Horatio N Jensen
1241
+ #{jpeg_photo_attribute}
1242
+ objectclass: organizationalPerson
1243
+ objectclass: person
1244
+ objectclass: top
1245
+ sn: Jensen
1246
+ telephonenumber: +1 408 555 1212
1247
+ uid: hjensen
1248
+ EOL
1249
+ end
1250
+
1251
+ def test_records_with_option_attributes
1252
+ ldif_source = <<-EOL
1253
+ version: 1
1254
+ dn:: b3U95Za25qWt6YOoLG89QWlyaXVz
1255
+ # dn:: ou=<JapaneseOU>,o=Airius
1256
+ objectclass: top
1257
+ objectclass: organizationalUnit
1258
+ ou:: 5Za25qWt6YOo
1259
+ # ou:: <JapaneseOU>
1260
+ ou;lang-ja:: 5Za25qWt6YOo
1261
+ # ou;lang-ja:: <JapaneseOU>
1262
+ ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2
1263
+ # ou;lang-ja:: <JapaneseOU_in_phonetic_representation>
1264
+ ou;lang-en: Sales
1265
+ description: Japanese office
1266
+
1267
+ dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz
1268
+ # dn:: uid=<uid>,ou=<JapaneseOU>,o=Airius
1269
+ userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM=
1270
+ objectclass: top
1271
+ objectclass: person
1272
+ objectclass: organizationalPerson
1273
+ objectclass: inetOrgPerson
1274
+ uid: rogasawara
1275
+ mail: rogasawara@airius.co.jp
1276
+ givenname;lang-ja:: 44Ot44OJ44OL44O8
1277
+ # givenname;lang-ja:: <JapaneseGivenname>
1278
+ sn;lang-ja:: 5bCP56yg5Y6f
1279
+ # sn;lang-ja:: <JapaneseSn>
1280
+ cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
1281
+ # cn;lang-ja:: <JapaneseCn>
1282
+ title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw==
1283
+ # title;lang-ja:: <JapaneseTitle>
1284
+ preferredlanguage: ja
1285
+ givenname:: 44Ot44OJ44OL44O8
1286
+ # givenname:: <JapaneseGivenname>
1287
+ sn:: 5bCP56yg5Y6f
1288
+ # sn:: <JapaneseSn>
1289
+ cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
1290
+ # cn:: <JapaneseCn>
1291
+ title:: 5Za25qWt6YOoIOmDqOmVtw==
1292
+ # title:: <JapaneseTitle>
1293
+ givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8
1294
+ # givenname;lang-ja;phonetic::
1295
+ <JapaneseGivenname_in_phonetic_representation_kana>
1296
+ sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ
1297
+ # sn;lang-ja;phonetic:: <JapaneseSn_in_phonetic_representation_kana>
1298
+ cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA==
1299
+ # cn;lang-ja;phonetic:: <JapaneseCn_in_phonetic_representation_kana>
1300
+ title;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg==
1301
+ # title;lang-ja;phonetic::
1302
+ # <JapaneseTitle_in_phonetic_representation_kana>
1303
+ givenname;lang-en: Rodney
1304
+ sn;lang-en: Ogasawara
1305
+ cn;lang-en: Rodney Ogasawara
1306
+ title;lang-en: Sales, Director
1307
+ EOL
1308
+ set_encoding(ldif_source, "utf-8")
1309
+
1310
+ record1 = {
1311
+ "dn" => "ou=営業部,o=Airius",
1312
+ "objectclass" => ["top", "organizationalUnit"],
1313
+ "ou" => [
1314
+ "営業部",
1315
+ {"lang-ja" =>
1316
+ [
1317
+ "営業部",
1318
+ {"phonetic" => ["えいぎょうぶ"]},
1319
+ ],
1320
+ },
1321
+ {"lang-en" => ["Sales"]},
1322
+ ],
1323
+ "description" => ["Japanese office"],
1324
+ }
1325
+
1326
+ record2 = {
1327
+ "dn" => "uid=rogasawara,ou=営業部,o=Airius",
1328
+ "userpassword" => ["{SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM="],
1329
+ "objectclass" => ["top", "person",
1330
+ "organizationalPerson", "inetOrgPerson"],
1331
+ "uid" => ["rogasawara"],
1332
+ "mail" => ["rogasawara@airius.co.jp"],
1333
+ "givenname" => [
1334
+ {"lang-ja" =>
1335
+ [
1336
+ "ロドニー",
1337
+ {"phonetic" => ["ろどにー"]},
1338
+ ]
1339
+ },
1340
+ "ロドニー",
1341
+ {"lang-en" => ["Rodney"]},
1342
+ ],
1343
+ "sn" => [
1344
+ {"lang-ja" =>
1345
+ [
1346
+ "小笠原",
1347
+ {"phonetic" => ["おがさわら"]},
1348
+ ]
1349
+ },
1350
+ "小笠原",
1351
+ {"lang-en" => ["Ogasawara"]},
1352
+ ],
1353
+ "cn" => [
1354
+ {"lang-ja" =>
1355
+ [
1356
+ "小笠原 ロドニー",
1357
+ {"phonetic" => ["おがさわら ろどにー"]},
1358
+ ],
1359
+ },
1360
+ "小笠原 ロドニー",
1361
+ {"lang-en" => ["Rodney Ogasawara"]},
1362
+ ],
1363
+ "title" => [
1364
+ {"lang-ja" =>
1365
+ [
1366
+ "営業部 部長",
1367
+ {"phonetic" => ["えいぎょうぶ ぶちょう"]}
1368
+ ]
1369
+ },
1370
+ "営業部 部長",
1371
+ {"lang-en" => ["Sales, Director"]},
1372
+ ],
1373
+ "preferredlanguage" => ["ja"],
1374
+ }
1375
+
1376
+ assert_ldif(1, [record1, record2], ldif_source)
1377
+ end
1378
+
1379
+ def test_records_with_option_attributes_to_s
1380
+ ldif_source = <<-EOL
1381
+ version: 1
1382
+ dn:: b3U95Za25qWt6YOoLG89QWlyaXVz
1383
+ # dn:: ou=<JapaneseOU>,o=Airius
1384
+ objectclass: top
1385
+ objectclass: organizationalUnit
1386
+ ou:: 5Za25qWt6YOo
1387
+ # ou:: <JapaneseOU>
1388
+ ou;lang-ja:: 5Za25qWt6YOo
1389
+ # ou;lang-ja:: <JapaneseOU>
1390
+ ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2
1391
+ # ou;lang-ja:: <JapaneseOU_in_phonetic_representation>
1392
+ ou;lang-en: Sales
1393
+ description: Japanese office
1394
+
1395
+ dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz
1396
+ # dn:: uid=<uid>,ou=<JapaneseOU>,o=Airius
1397
+ userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM=
1398
+ objectclass: top
1399
+ objectclass: person
1400
+ objectclass: organizationalPerson
1401
+ objectclass: inetOrgPerson
1402
+ uid: rogasawara
1403
+ mail: rogasawara@airius.co.jp
1404
+ givenname;lang-ja:: 44Ot44OJ44OL44O8
1405
+ # givenname;lang-ja:: <JapaneseGivenname>
1406
+ sn;lang-ja:: 5bCP56yg5Y6f
1407
+ # sn;lang-ja:: <JapaneseSn>
1408
+ cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
1409
+ # cn;lang-ja:: <JapaneseCn>
1410
+ title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw==
1411
+ # title;lang-ja:: <JapaneseTitle>
1412
+ preferredlanguage: ja
1413
+ givenname:: 44Ot44OJ44OL44O8
1414
+ # givenname:: <JapaneseGivenname>
1415
+ sn:: 5bCP56yg5Y6f
1416
+ # sn:: <JapaneseSn>
1417
+ cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
1418
+ # cn:: <JapaneseCn>
1419
+ title:: 5Za25qWt6YOoIOmDqOmVtw==
1420
+ # title:: <JapaneseTitle>
1421
+ givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8
1422
+ # givenname;lang-ja;phonetic::
1423
+ <JapaneseGivenname_in_phonetic_representation_kana>
1424
+ sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ
1425
+ # sn;lang-ja;phonetic:: <JapaneseSn_in_phonetic_representation_kana>
1426
+ cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA==
1427
+ # cn;lang-ja;phonetic:: <JapaneseCn_in_phonetic_representation_kana>
1428
+ title;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg==
1429
+ # title;lang-ja;phonetic::
1430
+ # <JapaneseTitle_in_phonetic_representation_kana>
1431
+ givenname;lang-en: Rodney
1432
+ sn;lang-en: Ogasawara
1433
+ cn;lang-en: Rodney Ogasawara
1434
+ title;lang-en: Sales, Director
1435
+ EOL
1436
+ set_encoding(ldif_source, "utf-8")
1437
+
1438
+ assert_ldif_to_s(<<-EOL, ldif_source)
1439
+ version: 1
1440
+ dn:: b3U95Za25qWt6YOoLG89QWlyaXVz
1441
+ description: Japanese office
1442
+ objectclass: organizationalUnit
1443
+ objectclass: top
1444
+ ou:: 5Za25qWt6YOo
1445
+ ou;lang-en: Sales
1446
+ ou;lang-ja:: 5Za25qWt6YOo
1447
+ ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2
1448
+
1449
+ dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz
1450
+ cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
1451
+ cn;lang-en: Rodney Ogasawara
1452
+ cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
1453
+ cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA==
1454
+ givenname:: 44Ot44OJ44OL44O8
1455
+ givenname;lang-en: Rodney
1456
+ givenname;lang-ja:: 44Ot44OJ44OL44O8
1457
+ givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8
1458
+ mail: rogasawara@airius.co.jp
1459
+ objectclass: inetOrgPerson
1460
+ objectclass: organizationalPerson
1461
+ objectclass: person
1462
+ objectclass: top
1463
+ preferredlanguage: ja
1464
+ sn:: 5bCP56yg5Y6f
1465
+ sn;lang-en: Ogasawara
1466
+ sn;lang-ja:: 5bCP56yg5Y6f
1467
+ sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ
1468
+ title:: 5Za25qWt6YOoIOmDqOmVtw==
1469
+ title;lang-en: Sales, Director
1470
+ title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw==
1471
+ title;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg==
1472
+ uid: rogasawara
1473
+ userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM=
1474
+ EOL
1475
+ end
1476
+
1477
+ def test_an_record_with_base64_encoded_value
1478
+ ldif_source = <<-EOL
1479
+ version: 1
1480
+ dn: cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com
1481
+ objectclass: top
1482
+ objectclass: person
1483
+ objectclass: organizationalPerson
1484
+ cn: Gern Jensen
1485
+ cn: Gern O Jensen
1486
+ sn: Jensen
1487
+ uid: gernj
1488
+ telephonenumber: +1 408 555 1212
1489
+ description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVl
1490
+ IGlzIGJhc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdG
1491
+ VyIGluIGl0IChhIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQg
1492
+ b3V0IG1vcmUu
1493
+ EOL
1494
+
1495
+ record = {
1496
+ "dn" => "cn=Gern Jensen,ou=Product Testing,dc=airius,dc=com",
1497
+ "objectclass" => ["top", "person", "organizationalPerson"],
1498
+ "cn" => ["Gern Jensen", "Gern O Jensen"],
1499
+ "sn" => ["Jensen"],
1500
+ "uid" => ["gernj"],
1501
+ "telephonenumber" => ["+1 408 555 1212"],
1502
+ "description" => ["What a careful reader you are! " +
1503
+ "This value is base-64-encoded because it has a " +
1504
+ "control character in it (a CR).\r By the way, " +
1505
+ "you should really get out more."],
1506
+ }
1507
+ assert_ldif(1, [record], ldif_source)
1508
+ end
1509
+
1510
+ def test_an_record_with_base64_encoded_value_to_s
1511
+ ldif_source = <<-EOL
1512
+ version: 1
1513
+ dn: cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com
1514
+ objectclass: top
1515
+ objectclass: person
1516
+ objectclass: organizationalPerson
1517
+ cn: Gern Jensen
1518
+ cn: Gern O Jensen
1519
+ sn: Jensen
1520
+ uid: gernj
1521
+ telephonenumber: +1 408 555 1212
1522
+ description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVl
1523
+ IGlzIGJhc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdG
1524
+ VyIGluIGl0IChhIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQg
1525
+ b3V0IG1vcmUu
1526
+ EOL
1527
+
1528
+ assert_ldif_to_s(<<-EOL, ldif_source)
1529
+ version: 1
1530
+ dn: cn=Gern Jensen,ou=Product Testing,dc=airius,dc=com
1531
+ cn: Gern Jensen
1532
+ cn: Gern O Jensen
1533
+ description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVlIGlzI
1534
+ GJhc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdGVyIGluIGl
1535
+ 0IChhIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQgb3V0IG1vcmUu
1536
+ objectclass: organizationalPerson
1537
+ objectclass: person
1538
+ objectclass: top
1539
+ sn: Jensen
1540
+ telephonenumber: +1 408 555 1212
1541
+ uid: gernj
1542
+ EOL
1543
+ end
1544
+
1545
+ def test_an_record_with_folded_attribute_value
1546
+ ldif_source = <<-EOL
1547
+ version: 1
1548
+ dn:cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
1549
+ objectclass:top
1550
+ objectclass:person
1551
+ objectclass:organizationalPerson
1552
+ cn:Barbara Jensen
1553
+ cn:Barbara J Jensen
1554
+ cn:Babs Jensen
1555
+ sn:Jensen
1556
+ uid:bjensen
1557
+ telephonenumber:+1 408 555 1212
1558
+ description:Babs is a big sailing fan, and travels extensively in sea
1559
+ rch of perfect sailing conditions.
1560
+ title:Product Manager, Rod and Reel Division
1561
+ EOL
1562
+
1563
+ record = {
1564
+ "dn" => "cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com",
1565
+ "objectclass" => ["top", "person", "organizationalPerson"],
1566
+ "cn" => ["Barbara Jensen", "Barbara J Jensen", "Babs Jensen"],
1567
+ "sn" => ["Jensen"],
1568
+ "uid" => ["bjensen"],
1569
+ "telephonenumber" => ["+1 408 555 1212"],
1570
+ "description" => ["Babs is a big sailing fan, and travels extensively " +
1571
+ "in search of perfect sailing conditions."],
1572
+ "title" => ["Product Manager, Rod and Reel Division"],
1573
+ }
1574
+ assert_ldif(1, [record], ldif_source)
1575
+ end
1576
+
1577
+ def test_an_record_with_folded_attribute_value_to_s
1578
+ ldif_source = <<-EOL
1579
+ version: 1
1580
+ dn:cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
1581
+ objectclass:top
1582
+ objectclass:person
1583
+ objectclass:organizationalPerson
1584
+ cn:Barbara Jensen
1585
+ cn:Barbara J Jensen
1586
+ cn:Babs Jensen
1587
+ sn:Jensen
1588
+ uid:bjensen
1589
+ telephonenumber:+1 408 555 1212
1590
+ description:Babs is a big sailing fan, and travels extensively in sea
1591
+ rch of perfect sailing conditions.
1592
+ title:Product Manager, Rod and Reel Division
1593
+ EOL
1594
+
1595
+ assert_ldif_to_s(<<-EOL, ldif_source)
1596
+ version: 1
1597
+ dn: cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com
1598
+ cn: Babs Jensen
1599
+ cn: Barbara J Jensen
1600
+ cn: Barbara Jensen
1601
+ description: Babs is a big sailing fan, and travels extensively in search o
1602
+ f perfect sailing conditions.
1603
+ objectclass: organizationalPerson
1604
+ objectclass: person
1605
+ objectclass: top
1606
+ sn: Jensen
1607
+ telephonenumber: +1 408 555 1212
1608
+ title: Product Manager, Rod and Reel Division
1609
+ uid: bjensen
1610
+ EOL
1611
+ end
1612
+
1613
+ def test_records
1614
+ ldif_source = <<-EOL
1615
+ version: 1
1616
+ dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
1617
+ objectclass: top
1618
+ objectclass: person
1619
+ objectclass: organizationalPerson
1620
+ cn: Barbara Jensen
1621
+ cn: Barbara J Jensen
1622
+ cn: Babs Jensen
1623
+ sn: Jensen
1624
+ uid: bjensen
1625
+ telephonenumber: +1 408 555 1212
1626
+ description: A big sailing fan.
1627
+
1628
+ dn: cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com
1629
+ objectclass: top
1630
+ objectclass: person
1631
+ objectclass: organizationalPerson
1632
+ cn: Bjorn Jensen
1633
+ sn: Jensen
1634
+ telephonenumber: +1 408 555 1212
1635
+ EOL
1636
+
1637
+ record1 = {
1638
+ "dn" => "cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com",
1639
+ "objectclass" => ["top", "person", "organizationalPerson"],
1640
+ "cn" => ["Barbara Jensen", "Barbara J Jensen", "Babs Jensen"],
1641
+ "sn" => ["Jensen"],
1642
+ "uid" => ["bjensen"],
1643
+ "telephonenumber" => ["+1 408 555 1212"],
1644
+ "description" => ["A big sailing fan."],
1645
+ }
1646
+ record2 = {
1647
+ "dn" => "cn=Bjorn Jensen,ou=Accounting,dc=airius,dc=com",
1648
+ "objectclass" => ["top", "person", "organizationalPerson"],
1649
+ "cn" => ["Bjorn Jensen"],
1650
+ "sn" => ["Jensen"],
1651
+ "telephonenumber" => ["+1 408 555 1212"],
1652
+ }
1653
+ assert_ldif(1, [record1, record2], ldif_source)
1654
+ end
1655
+
1656
+ def test_records_to_s
1657
+ ldif_source = <<-EOL
1658
+ version: 1
1659
+ dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
1660
+ objectclass: top
1661
+ objectclass: person
1662
+ objectclass: organizationalPerson
1663
+ cn: Barbara Jensen
1664
+ cn: Barbara J Jensen
1665
+ cn: Babs Jensen
1666
+ sn: Jensen
1667
+ uid: bjensen
1668
+ telephonenumber: +1 408 555 1212
1669
+ description: A big sailing fan.
1670
+
1671
+ dn: cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com
1672
+ objectclass: top
1673
+ objectclass: person
1674
+ objectclass: organizationalPerson
1675
+ cn: Bjorn Jensen
1676
+ sn: Jensen
1677
+ telephonenumber: +1 408 555 1212
1678
+ EOL
1679
+
1680
+ assert_ldif_to_s(<<-EOL, ldif_source)
1681
+ version: 1
1682
+ dn: cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com
1683
+ cn: Babs Jensen
1684
+ cn: Barbara J Jensen
1685
+ cn: Barbara Jensen
1686
+ description: A big sailing fan.
1687
+ objectclass: organizationalPerson
1688
+ objectclass: person
1689
+ objectclass: top
1690
+ sn: Jensen
1691
+ telephonenumber: +1 408 555 1212
1692
+ uid: bjensen
1693
+
1694
+ dn: cn=Bjorn Jensen,ou=Accounting,dc=airius,dc=com
1695
+ cn: Bjorn Jensen
1696
+ objectclass: organizationalPerson
1697
+ objectclass: person
1698
+ objectclass: top
1699
+ sn: Jensen
1700
+ telephonenumber: +1 408 555 1212
1701
+ EOL
1702
+ end
1703
+
1704
+ def test_an_record
1705
+ ldif_source = <<-EOL
1706
+ version: 1
1707
+ dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
1708
+ objectclass: top
1709
+ objectclass: person
1710
+ objectclass: organizationalPerson
1711
+ cn: Barbara Jensen
1712
+ cn: Barbara J Jensen
1713
+ cn: Babs Jensen
1714
+ sn: Jensen
1715
+ uid: bjensen
1716
+ telephonenumber: +1 408 555 1212
1717
+ description: A big sailing fan.
1718
+ EOL
1719
+
1720
+ record = {
1721
+ "dn" => "cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com",
1722
+ "objectclass" => ["top", "person", "organizationalPerson"],
1723
+ "cn" => ["Barbara Jensen", "Barbara J Jensen", "Babs Jensen"],
1724
+ "sn" => ["Jensen"],
1725
+ "uid" => ["bjensen"],
1726
+ "telephonenumber" => ["+1 408 555 1212"],
1727
+ "description" => ["A big sailing fan."],
1728
+ }
1729
+ assert_ldif(1, [record], ldif_source)
1730
+ end
1731
+
1732
+ def test_an_record_to_s
1733
+ ldif_source = <<-EOL
1734
+ version: 1
1735
+ dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
1736
+ objectclass: top
1737
+ objectclass: person
1738
+ objectclass: organizationalPerson
1739
+ cn: Barbara Jensen
1740
+ cn: Barbara J Jensen
1741
+ cn: Babs Jensen
1742
+ sn: Jensen
1743
+ uid: bjensen
1744
+ telephonenumber: +1 408 555 1212
1745
+ description: A big sailing fan.
1746
+ EOL
1747
+
1748
+ assert_ldif_to_s(<<-EOL, ldif_source)
1749
+ version: 1
1750
+ dn: cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com
1751
+ cn: Babs Jensen
1752
+ cn: Barbara J Jensen
1753
+ cn: Barbara Jensen
1754
+ description: A big sailing fan.
1755
+ objectclass: organizationalPerson
1756
+ objectclass: person
1757
+ objectclass: top
1758
+ sn: Jensen
1759
+ telephonenumber: +1 408 555 1212
1760
+ uid: bjensen
1761
+ EOL
1762
+ end
1763
+
1764
+ def test_comment
1765
+ ldif_source = <<-EOL
1766
+ version: 1
1767
+ dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
1768
+ objectclass: top
1769
+ # objectclass: person
1770
+ #objectcl
1771
+ ass: organizationalPerson
1772
+ EOL
1773
+
1774
+ record = {
1775
+ "dn" => "cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com",
1776
+ "objectclass" => ["top"],
1777
+ }
1778
+ assert_ldif(1, [record], ldif_source)
1779
+ end
1780
+
1781
+ def test_comment_to_s
1782
+ ldif_source = <<-EOL
1783
+ version: 1
1784
+ dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
1785
+ objectclass: top
1786
+ # objectclass: person
1787
+ #objectcl
1788
+ ass: organizationalPerson
1789
+ EOL
1790
+
1791
+ assert_ldif_to_s(<<-EOL, ldif_source)
1792
+ version: 1
1793
+ dn: cn=Barbara Jensen,ou=Product Development,dc=airius,dc=com
1794
+ objectclass: top
1795
+ EOL
1796
+ end
1797
+
1798
+ def test_dn_spec
1799
+ assert_invalid_ldif("'dn:' is missing",
1800
+ "version: 1\n", 2, 1, "version: 1\n|@|")
1801
+ assert_invalid_ldif("DN is missing",
1802
+ "version: 1\ndn:", 2, 4, "dn:|@|")
1803
+ assert_invalid_ldif("DN is missing",
1804
+ "version: 1\ndn::", 2, 5, "dn::|@|")
1805
+ assert_invalid_ldif("DN is missing",
1806
+ "version: 1\ndn:\n", 2, 4, "dn:|@|\n")
1807
+ assert_invalid_ldif("DN is missing",
1808
+ "version: 1\ndn: \n", 2, 5, "dn: |@|\n")
1809
+
1810
+ dn = "cn=Barbara Jensen,ou=Product Development,dc=example,dc=com"
1811
+ cn = "Barbara Jensen"
1812
+ assert_valid_dn(dn, "version: 1\ndn: #{dn}\ncn:#{cn}\n")
1813
+
1814
+ encoded_dn = Base64.encode64(dn).gsub(/\n/, "\n ")
1815
+ encoded_cn = Base64.encode64(cn).gsub(/\n/, "\n ")
1816
+ assert_valid_dn(dn, "version: 1\ndn:: #{encoded_dn}\ncn::#{encoded_cn}\n")
1817
+ end
1818
+
1819
+ def test_version_number
1820
+ assert_valid_version(1, "version: 1\ndn: dc=com\ndc: com")
1821
+ assert_valid_version(1, "version: 1\r\ndn: dc=com\ndc: com\n")
1822
+ assert_valid_version(1, "version: 1\r\n\n\r\n\ndn: dc=com\ndc: com\n")
1823
+
1824
+ assert_invalid_ldif(["unsupported version: %d", 0],
1825
+ "version: 0", 1, 11, "version: 0|@|")
1826
+ assert_invalid_ldif(["unsupported version: %d", 2],
1827
+ "version: 2", 1, 11, "version: 2|@|")
1828
+
1829
+ assert_invalid_ldif("separator is missing",
1830
+ "version: 1", 1, 11, "version: 1|@|")
1831
+ end
1832
+
1833
+ def test_version_spec
1834
+ assert_invalid_ldif("version spec is missing",
1835
+ "", 1, 1, "|@|")
1836
+ assert_invalid_ldif("version spec is missing",
1837
+ "VERSION: 1", 1, 1, "|@|VERSION: 1")
1838
+ assert_invalid_ldif("version number is missing",
1839
+ "version:", 1, 9, "version:|@|")
1840
+ assert_invalid_ldif("version number is missing",
1841
+ "version: ", 1, 10, "version: |@|")
1842
+ assert_invalid_ldif("version number is missing",
1843
+ "version: XXX", 1, 10, "version: |@|XXX")
1844
+ end
1845
+
1846
+ private
1847
+ def assert_ldif(version, records, ldif_source)
1848
+ encoding = ldif_source.encoding if ldif_source.respond_to?(:encoding)
1849
+ ldif = ActiveLdap::Ldif.parse(ldif_source)
1850
+ assert_equal(version, ldif.version)
1851
+ assert_equal(records,
1852
+ ldif.records.collect {|record| record.to_hash})
1853
+
1854
+ regenerated_ldif = ldif.to_s
1855
+ set_encoding(regenerated_ldif, encoding)
1856
+ reparsed_ldif = ActiveLdap::Ldif.parse(regenerated_ldif)
1857
+ assert_equal(ldif, reparsed_ldif)
1858
+
1859
+ ldif
1860
+ end
1861
+
1862
+ def assert_valid_dn(dn, ldif_source)
1863
+ ldif = ActiveLdap::Ldif.parse(ldif_source)
1864
+ assert_equal([dn], ldif.records.collect {|record| record.dn})
1865
+ end
1866
+
1867
+ def assert_valid_version(version, ldif_source)
1868
+ ldif = ActiveLdap::Ldif.parse(ldif_source)
1869
+ assert_equal(version, ldif.version)
1870
+ end
1871
+
1872
+ def assert_invalid_ldif(reason, ldif, line, column, nearest)
1873
+ exception = assert_raise(ActiveLdap::LdifInvalid) do
1874
+ ActiveLdap::Ldif.parse(ldif)
1875
+ end
1876
+ reason, *params = reason
1877
+ params = params.collect {|param| param.is_a?(String) ? _(param) : param}
1878
+ assert_equal([_(reason) % params, line, column, nearest, ldif],
1879
+ [exception.reason, exception.line, exception.column,
1880
+ exception.nearest, exception.ldif])
1881
+ end
1882
+
1883
+ def assert_ldif_to_s(expected_ldif_source, original_ldif_source)
1884
+ ldif = ActiveLdap::Ldif.parse(original_ldif_source)
1885
+ assert_equal(expected_ldif_source, ldif.to_s)
1886
+ end
1887
+
1888
+ def set_encoding(string, encoding)
1889
+ string.force_encoding("utf-8") if string.respond_to?(:force_encoding)
1890
+ end
1891
+ end