Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Copy plugins to release branch

  • Loading branch information...
commit 5da48a95224e925f4b070f2581a121516df33829 1 parent b03854d
@thomascube thomascube authored
Showing with 28,028 additions and 0 deletions.
  1. +341 −0 plugins/acl/acl.js
  2. +701 −0 plugins/acl/acl.php
  3. +19 −0 plugins/acl/config.inc.php.dist
  4. +83 −0 plugins/acl/localization/de_DE.inc
  5. +83 −0 plugins/acl/localization/en_US.inc
  6. +83 −0 plugins/acl/localization/pl_PL.inc
  7. +100 −0 plugins/acl/skins/default/acl.css
  8. BIN  plugins/acl/skins/default/images/enabled.png
  9. BIN  plugins/acl/skins/default/images/partial.png
  10. +54 −0 plugins/acl/skins/default/templates/table.html
  11. +43 −0 plugins/additional_message_headers/additional_message_headers.php
  12. +14 −0 plugins/additional_message_headers/config.inc.php.dist
  13. +47 −0 plugins/additional_message_headers/package.xml
  14. +34 −0 plugins/archive/archive.js
  15. +124 −0 plugins/archive/archive.php
  16. +25 −0 plugins/archive/localization/cs_CZ.inc
  17. +8 −0 plugins/archive/localization/de_CH.inc
  18. +8 −0 plugins/archive/localization/de_DE.inc
  19. +8 −0 plugins/archive/localization/en_US.inc
  20. +10 −0 plugins/archive/localization/es_AR.inc
  21. +10 −0 plugins/archive/localization/es_ES.inc
  22. +8 −0 plugins/archive/localization/et_EE.inc
  23. +8 −0 plugins/archive/localization/fr_FR.inc
  24. +10 −0 plugins/archive/localization/gl_ES.inc
  25. +10 −0 plugins/archive/localization/ja_JP.inc
  26. +8 −0 plugins/archive/localization/nl_NL.inc
  27. +8 −0 plugins/archive/localization/pl_PL.inc
  28. +8 −0 plugins/archive/localization/pt_BR.inc
  29. +8 −0 plugins/archive/localization/ru_RU.inc
  30. +8 −0 plugins/archive/localization/sv_SE.inc
  31. +8 −0 plugins/archive/localization/zh_TW.inc
  32. +64 −0 plugins/archive/package.xml
  33. BIN  plugins/archive/skins/default/archive_act.png
  34. BIN  plugins/archive/skins/default/archive_pas.png
  35. BIN  plugins/archive/skins/default/foldericon.png
  36. +47 −0 plugins/autologon/autologon.php
  37. +168 −0 plugins/database_attachments/database_attachments.php
  38. +146 −0 plugins/debug_logger/debug_logger.php
  39. +227 −0 plugins/debug_logger/runlog/runlog.php
  40. +77 −0 plugins/emoticons/emoticons.php
  41. +35 −0 plugins/enigma/README
  42. +14 −0 plugins/enigma/config.inc.php.dist
  43. +206 −0 plugins/enigma/enigma.js
  44. +475 −0 plugins/enigma/enigma.php
  45. +2 −0  plugins/enigma/home/.htaccess
  46. +2,542 −0 plugins/enigma/lib/Crypt/GPG.php
  47. +336 −0 plugins/enigma/lib/Crypt/GPG/DecryptStatusHandler.php
  48. +1,758 −0 plugins/enigma/lib/Crypt/GPG/Engine.php
  49. +473 −0 plugins/enigma/lib/Crypt/GPG/Exceptions.php
  50. +223 −0 plugins/enigma/lib/Crypt/GPG/Key.php
  51. +428 −0 plugins/enigma/lib/Crypt/GPG/Signature.php
  52. +649 −0 plugins/enigma/lib/Crypt/GPG/SubKey.php
  53. +373 −0 plugins/enigma/lib/Crypt/GPG/UserId.php
  54. +216 −0 plugins/enigma/lib/Crypt/GPG/VerifyStatusHandler.php
  55. +106 −0 plugins/enigma/lib/enigma_driver.php
  56. +305 −0 plugins/enigma/lib/enigma_driver_gnupg.php
  57. +547 −0 plugins/enigma/lib/enigma_engine.php
  58. +62 −0 plugins/enigma/lib/enigma_error.php
  59. +129 −0 plugins/enigma/lib/enigma_key.php
  60. +34 −0 plugins/enigma/lib/enigma_signature.php
  61. +57 −0 plugins/enigma/lib/enigma_subkey.php
  62. +459 −0 plugins/enigma/lib/enigma_ui.php
  63. +31 −0 plugins/enigma/lib/enigma_userid.php
  64. +53 −0 plugins/enigma/localization/en_US.inc
  65. +55 −0 plugins/enigma/localization/ja_JP.inc
  66. +65 −0 plugins/enigma/localization/ru_RU.inc
  67. +182 −0 plugins/enigma/skins/default/enigma.css
  68. BIN  plugins/enigma/skins/default/enigma.png
  69. BIN  plugins/enigma/skins/default/enigma_error.png
  70. BIN  plugins/enigma/skins/default/key.png
  71. BIN  plugins/enigma/skins/default/key_add.png
  72. BIN  plugins/enigma/skins/default/keys_toolbar.png
  73. +20 −0 plugins/enigma/skins/default/templates/keyimport.html
  74. +17 −0 plugins/enigma/skins/default/templates/keyinfo.html
  75. +76 −0 plugins/enigma/skins/default/templates/keys.html
  76. +50 −0 plugins/example_addressbook/example_addressbook.php
  77. +116 −0 plugins/example_addressbook/example_addressbook_backend.php
  78. +161 −0 plugins/filesystem_attachments/filesystem_attachments.php
  79. +5 −0 plugins/help/config.inc.php.dist
  80. +39 −0 plugins/help/content/about.html
  81. +387 −0 plugins/help/content/license.html
  82. +107 −0 plugins/help/help.php
  83. +25 −0 plugins/help/localization/cs_CZ.inc
  84. +8 −0 plugins/help/localization/da_DK.inc
  85. +8 −0 plugins/help/localization/de_DE.inc
  86. +8 −0 plugins/help/localization/en_GB.inc
  87. +8 −0 plugins/help/localization/en_US.inc
  88. +8 −0 plugins/help/localization/es_ES.inc
  89. +8 −0 plugins/help/localization/et_EE.inc
  90. +8 −0 plugins/help/localization/gl_ES.inc
  91. +8 −0 plugins/help/localization/hu_HU.inc
  92. +10 −0 plugins/help/localization/ja_JP.inc
  93. +8 −0 plugins/help/localization/pl_PL.inc
  94. +8 −0 plugins/help/localization/pt_BR.inc
  95. +23 −0 plugins/help/localization/ru_RU.inc
  96. +8 −0 plugins/help/localization/sv_SE.inc
  97. +8 −0 plugins/help/localization/zh_TW.inc
  98. +29 −0 plugins/help/skins/default/help.css
  99. BIN  plugins/help/skins/default/help.gif
  100. +37 −0 plugins/help/skins/default/templates/help.html
  101. +66 −0 plugins/http_authentication/http_authentication.php
  102. +29 −0 plugins/http_authentication/logout.html
  103. +29 −0 plugins/jqueryui/README
  104. +11 −0 plugins/jqueryui/config.inc.php.dist
  105. +54 −0 plugins/jqueryui/jqueryui.php
  106. +1,242 −0 plugins/jqueryui/js/i18n/jquery-ui-i18n.js
  107. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-af.js
  108. +24 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-ar.js
  109. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-az.js
  110. +24 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-bg.js
  111. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-bs.js
  112. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-ca.js
  113. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-cs.js
  114. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-da.js
  115. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-de-CH.js
  116. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-de.js
  117. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-el.js
  118. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-en-GB.js
  119. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-eo.js
  120. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-es.js
  121. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-et.js
  122. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-eu.js
  123. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-fa.js
  124. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-fi.js
  125. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-fo.js
  126. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr-CH.js
  127. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-fr.js
  128. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-gl.js
  129. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-he.js
  130. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-hr.js
  131. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-hu.js
  132. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-hy.js
  133. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-id.js
  134. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-is.js
  135. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-it.js
  136. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-ja.js
  137. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-ko.js
  138. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-kz.js
  139. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-lt.js
  140. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-lv.js
  141. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-ms.js
  142. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl-BE.js
  143. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-nl.js
  144. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-no.js
  145. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-pl.js
  146. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt-BR.js
  147. +22 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-pt.js
  148. +26 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-ro.js
  149. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-ru.js
  150. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-sk.js
  151. +24 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-sl.js
  152. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-sq.js
  153. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr-SR.js
  154. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-sr.js
  155. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-sv.js
  156. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-ta.js
  157. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-th.js
  158. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-tr.js
  159. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-uk.js
  160. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-vi.js
  161. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-CN.js
  162. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-HK.js
  163. +23 −0 plugins/jqueryui/js/i18n/jquery.ui.datepicker-zh-TW.js
  164. +789 −0 plugins/jqueryui/js/jquery-ui-1.8.14.custom.min.js
  165. BIN  plugins/jqueryui/themes/default/images/buttongradient.png
  166. BIN  plugins/jqueryui/themes/default/images/listheader.png
  167. BIN  plugins/jqueryui/themes/default/images/ui-bg_flat_0_aaaaaa_40x100.png
  168. BIN  plugins/jqueryui/themes/default/images/ui-bg_flat_75_ffffff_40x100.png
  169. BIN  plugins/jqueryui/themes/default/images/ui-bg_flat_90_cc3333_40x100.png
  170. BIN  plugins/jqueryui/themes/default/images/ui-bg_glass_95_fef1ec_1x400.png
  171. BIN  plugins/jqueryui/themes/default/images/ui-bg_highlight-hard_90_a3a3a3_1x100.png
  172. BIN  plugins/jqueryui/themes/default/images/ui-bg_highlight-hard_90_e6e6e7_1x100.png
  173. BIN  plugins/jqueryui/themes/default/images/ui-bg_highlight-hard_90_f4f4f4_1x100.png
  174. BIN  plugins/jqueryui/themes/default/images/ui-icons_000000_256x240.png
  175. BIN  plugins/jqueryui/themes/default/images/ui-icons_333333_256x240.png
  176. BIN  plugins/jqueryui/themes/default/images/ui-icons_666666_256x240.png
  177. BIN  plugins/jqueryui/themes/default/images/ui-icons_cc3333_256x240.png
  178. BIN  plugins/jqueryui/themes/default/images/ui-icons_dddddd_256x240.png
  179. +580 −0 plugins/jqueryui/themes/default/jquery-ui-1.8.14.custom.css
  180. +124 −0 plugins/jqueryui/themes/default/roundcube-custom.diff
  181. BIN  plugins/jqueryui/themes/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png
  182. BIN  plugins/jqueryui/themes/redmond/images/ui-bg_flat_55_fbec88_40x100.png
  183. BIN  plugins/jqueryui/themes/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png
  184. BIN  plugins/jqueryui/themes/redmond/images/ui-bg_glass_85_dfeffc_1x400.png
  185. BIN  plugins/jqueryui/themes/redmond/images/ui-bg_glass_95_fef1ec_1x400.png
  186. BIN  plugins/jqueryui/themes/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png
  187. BIN  plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png
  188. BIN  plugins/jqueryui/themes/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
  189. BIN  plugins/jqueryui/themes/redmond/images/ui-icons_217bc0_256x240.png
  190. BIN  plugins/jqueryui/themes/redmond/images/ui-icons_2e83ff_256x240.png
  191. BIN  plugins/jqueryui/themes/redmond/images/ui-icons_469bdd_256x240.png
  192. BIN  plugins/jqueryui/themes/redmond/images/ui-icons_6da8d5_256x240.png
  193. BIN  plugins/jqueryui/themes/redmond/images/ui-icons_cd0a0a_256x240.png
  194. BIN  plugins/jqueryui/themes/redmond/images/ui-icons_d8e7f3_256x240.png
  195. BIN  plugins/jqueryui/themes/redmond/images/ui-icons_f9bd01_256x240.png
  196. +568 −0 plugins/jqueryui/themes/redmond/jquery-ui-1.8.14.custom.css
  197. +217 −0 plugins/managesieve/Changelog
  198. +67 −0 plugins/managesieve/config.inc.php.dist
  199. +1,274 −0 plugins/managesieve/lib/Net/Sieve.php
  200. +378 −0 plugins/managesieve/lib/rcube_sieve.php
  201. +940 −0 plugins/managesieve/lib/rcube_sieve_script.php
  202. +50 −0 plugins/managesieve/localization/bg_BG.inc
  203. +61 −0 plugins/managesieve/localization/cs_CZ.inc
  204. +52 −0 plugins/managesieve/localization/de_CH.inc
  205. +92 −0 plugins/managesieve/localization/de_DE.inc
  206. +56 −0 plugins/managesieve/localization/el_GR.inc
  207. +53 −0 plugins/managesieve/localization/en_GB.inc
  208. +119 −0 plugins/managesieve/localization/en_US.inc
  209. +81 −0 plugins/managesieve/localization/es_AR.inc
  210. +81 −0 plugins/managesieve/localization/es_ES.inc
  211. +53 −0 plugins/managesieve/localization/et_EE.inc
  212. +68 −0 plugins/managesieve/localization/fi_FI.inc
  213. +63 −0 plugins/managesieve/localization/fr_FR.inc
  214. +81 −0 plugins/managesieve/localization/gl_ES.inc
  215. +105 −0 plugins/managesieve/localization/hr_HR.inc
  216. +54 −0 plugins/managesieve/localization/hu_HU.inc
  217. +79 −0 plugins/managesieve/localization/it_IT.inc
  218. +82 −0 plugins/managesieve/localization/ja_JP.inc
  219. +92 −0 plugins/managesieve/localization/lv_LV.inc
  220. +54 −0 plugins/managesieve/localization/nb_NO.inc
  221. +49 −0 plugins/managesieve/localization/nl_NL.inc
  222. +118 −0 plugins/managesieve/localization/pl_PL.inc
  223. +53 −0 plugins/managesieve/localization/pt_BR.inc
  224. +185 −0 plugins/managesieve/localization/pt_PT.inc
  225. +117 −0 plugins/managesieve/localization/ru_RU.inc
  226. +85 −0 plugins/managesieve/localization/sk_SK.inc
  227. +53 −0 plugins/managesieve/localization/sl_SI.inc
  228. +93 −0 plugins/managesieve/localization/sv_SE.inc
  229. +76 −0 plugins/managesieve/localization/uk_UA.inc
  230. +49 −0 plugins/managesieve/localization/zh_CN.inc
  231. +78 −0 plugins/managesieve/localization/zh_TW.inc
  232. +731 −0 plugins/managesieve/managesieve.js
  233. +1,731 −0 plugins/managesieve/managesieve.php
  234. BIN  plugins/managesieve/skins/default/images/add.png
  235. BIN  plugins/managesieve/skins/default/images/del.png
  236. BIN  plugins/managesieve/skins/default/images/filter.png
  237. BIN  plugins/managesieve/skins/default/images/toolbar.png
  238. +283 −0 plugins/managesieve/skins/default/managesieve.css
  239. +63 −0 plugins/managesieve/skins/default/managesieve_mail.css
  240. +33 −0 plugins/managesieve/skins/default/templates/filteredit.html
  241. +87 −0 plugins/managesieve/skins/default/templates/managesieve.html
  242. +24 −0 plugins/managesieve/skins/default/templates/setedit.html
  243. +7 −0 plugins/managesieve/tests/Makefile
  244. +114 −0 plugins/managesieve/tests/parser.phpt
  245. +19 −0 plugins/managesieve/tests/parser_kep14.phpt
  246. +66 −0 plugins/managesieve/tests/tokenize.phpt
  247. +24 −0 plugins/markasjunk/localization/cs_CZ.inc
  248. +7 −0 plugins/markasjunk/localization/da_DK.inc
  249. +6 −0 plugins/markasjunk/localization/de_DE.inc
  250. +7 −0 plugins/markasjunk/localization/en_US.inc
  251. +7 −0 plugins/markasjunk/localization/es_AR.inc
  252. +7 −0 plugins/markasjunk/localization/es_ES.inc
  253. +7 −0 plugins/markasjunk/localization/et_EE.inc
  254. +7 −0 plugins/markasjunk/localization/gl_ES.inc
  255. +7 −0 plugins/markasjunk/localization/it_IT.inc
  256. +9 −0 plugins/markasjunk/localization/ja_JP.inc
  257. +7 −0 plugins/markasjunk/localization/pl_PL.inc
  258. +7 −0 plugins/markasjunk/localization/ru_RU.inc
  259. +15 −0 plugins/markasjunk/localization/sk_SK.inc
  260. +7 −0 plugins/markasjunk/localization/sv_SE.inc
  261. +7 −0 plugins/markasjunk/localization/zh_TW.inc
  262. +28 −0 plugins/markasjunk/markasjunk.js
  263. +58 −0 plugins/markasjunk/markasjunk.php
  264. +67 −0 plugins/markasjunk/package.xml
  265. BIN  plugins/markasjunk/skins/default/junk_act.png
  266. BIN  plugins/markasjunk/skins/default/junk_pas.png
  267. +7 −0 plugins/new_user_dialog/localization/bg_BG.inc
  268. +7 −0 plugins/new_user_dialog/localization/cs_CZ.inc
  269. +7 −0 plugins/new_user_dialog/localization/de_CH.inc
  270. +7 −0 plugins/new_user_dialog/localization/de_DE.inc
  271. +7 −0 plugins/new_user_dialog/localization/en_US.inc
  272. +7 −0 plugins/new_user_dialog/localization/es_ES.inc
  273. +7 −0 plugins/new_user_dialog/localization/et_EE.inc
  274. +7 −0 plugins/new_user_dialog/localization/gl_ES.inc
  275. +7 −0 plugins/new_user_dialog/localization/it_IT.inc
  276. +9 −0 plugins/new_user_dialog/localization/ja_JP.inc
  277. +7 −0 plugins/new_user_dialog/localization/nl_NL.inc
  278. +7 −0 plugins/new_user_dialog/localization/pl_PL.inc
  279. +7 −0 plugins/new_user_dialog/localization/pt_BR.inc
  280. +7 −0 plugins/new_user_dialog/localization/pt_PT.inc
  281. +7 −0 plugins/new_user_dialog/localization/ru_RU.inc
  282. +16 −0 plugins/new_user_dialog/localization/sk_SK.inc
  283. +7 −0 plugins/new_user_dialog/localization/sl_SI.inc
  284. +7 −0 plugins/new_user_dialog/localization/sv_SE.inc
  285. +7 −0 plugins/new_user_dialog/localization/zh_TW.inc
  286. +144 −0 plugins/new_user_dialog/new_user_dialog.php
  287. +60 −0 plugins/new_user_dialog/newuserdialog.css
  288. +139 −0 plugins/new_user_dialog/package.xml
  289. +89 −0 plugins/new_user_identity/new_user_identity.php
  290. +12 −0 plugins/newmail_notifier/config.inc.php.dist
  291. BIN  plugins/newmail_notifier/favicon.ico
  292. +13 −0 plugins/newmail_notifier/localization/de_CH.inc
  293. +13 −0 plugins/newmail_notifier/localization/de_DE.inc
  294. +13 −0 plugins/newmail_notifier/localization/en_US.inc
  295. +13 −0 plugins/newmail_notifier/localization/pl_PL.inc
  296. +13 −0 plugins/newmail_notifier/localization/pt_BR.inc
  297. +21 −0 plugins/newmail_notifier/localization/ru_RU.inc
  298. BIN  plugins/newmail_notifier/mail.png
  299. +120 −0 plugins/newmail_notifier/newmail_notifier.js
  300. +155 −0 plugins/newmail_notifier/newmail_notifier.php
Sorry, we could not display the entire diff because too many files (408) changed.
View
341 plugins/acl/acl.js
@@ -0,0 +1,341 @@
+/**
+ * ACL plugin script
+ *
+ * @version 0.6.2
+ * @author Aleksander Machniak <alec@alec.pl>
+ */
+
+if (window.rcmail) {
+ rcmail.addEventListener('init', function() {
+ if (rcmail.gui_objects.acltable) {
+ rcmail.acl_list_init();
+ // enable autocomplete on user input
+ if (rcmail.env.acl_users_source) {
+ rcmail.init_address_input_events($('#acluser'), {action:'settings/plugin.acl-autocomplete'});
+ // fix inserted value
+ rcmail.addEventListener('autocomplete_insert', function(e) {
+ if (e.field.id != 'acluser')
+ return;
+
+ var value = e.insert;
+ // get UID from the entry value
+ if (value.match(/\s*\(([^)]+)\)[, ]*$/))
+ value = RegExp.$1;
+ e.field.value = value;
+ });
+ }
+ }
+
+ rcmail.enable_command('acl-create', 'acl-save', 'acl-cancel', 'acl-mode-switch', true);
+ rcmail.enable_command('acl-delete', 'acl-edit', false);
+ });
+}
+
+// Display new-entry form
+rcube_webmail.prototype.acl_create = function()
+{
+ this.acl_init_form();
+}
+
+// Display ACL edit form
+rcube_webmail.prototype.acl_edit = function()
+{
+ // @TODO: multi-row edition
+ var id = this.acl_list.get_single_selection();
+ if (id)
+ this.acl_init_form(id);
+}
+
+// ACL entry delete
+rcube_webmail.prototype.acl_delete = function()
+{
+ var users = this.acl_get_usernames();
+
+ if (users && users.length && confirm(this.get_label('acl.deleteconfirm'))) {
+ this.http_request('settings/plugin.acl', '_act=delete&_user='+urlencode(users.join(','))
+ + '&_mbox='+urlencode(this.env.mailbox),
+ this.set_busy(true, 'acl.deleting'));
+ }
+}
+
+// Save ACL data
+rcube_webmail.prototype.acl_save = function()
+{
+ var user = $('#acluser').val(), rights = '', type;
+
+ $(':checkbox', this.env.acl_advanced ? $('#advancedrights') : sim_ul = $('#simplerights')).map(function() {
+ if (this.checked)
+ rights += this.value;
+ });
+
+ if (type = $('input:checked[name=usertype]').val()) {
+ if (type != 'user')
+ user = type;
+ }
+
+ if (!user) {
+ alert(this.get_label('acl.nouser'));
+ return;
+ }
+ if (!rights) {
+ alert(this.get_label('acl.norights'));
+ return;
+ }
+
+ this.http_request('settings/plugin.acl', '_act=save'
+ + '&_user='+urlencode(user)
+ + '&_acl=' +rights
+ + '&_mbox='+urlencode(this.env.mailbox)
+ + (this.acl_id ? '&_old='+this.acl_id : ''),
+ this.set_busy(true, 'acl.saving'));
+}
+
+// Cancel/Hide form
+rcube_webmail.prototype.acl_cancel = function()
+{
+ this.ksearch_blur();
+ this.acl_form.hide();
+}
+
+// Update data after save (and hide form)
+rcube_webmail.prototype.acl_update = function(o)
+{
+ // delete old row
+ if (o.old)
+ this.acl_remove_row(o.old);
+ // make sure the same ID doesn't exist
+ else if (this.env.acl[o.id])
+ this.acl_remove_row(o.id);
+
+ // add new row
+ this.acl_add_row(o, true);
+ // hide autocomplete popup
+ this.ksearch_blur();
+ // hide form
+ this.acl_form.hide();
+}
+
+// Switch table display mode
+rcube_webmail.prototype.acl_mode_switch = function(elem)
+{
+ this.env.acl_advanced = !this.env.acl_advanced;
+ this.enable_command('acl-delete', 'acl-edit', false);
+ this.http_request('settings/plugin.acl', '_act=list'
+ + '&_mode='+(this.env.acl_advanced ? 'advanced' : 'simple')
+ + '&_mbox='+urlencode(this.env.mailbox),
+ this.set_busy(true, 'loading'));
+}
+
+// ACL table initialization
+rcube_webmail.prototype.acl_list_init = function()
+{
+ this.acl_list = new rcube_list_widget(this.gui_objects.acltable,
+ {multiselect:true, draggable:false, keyboard:true, toggleselect:true});
+ this.acl_list.addEventListener('select', function(o) { rcmail.acl_list_select(o); });
+ this.acl_list.addEventListener('dblclick', function(o) { rcmail.acl_list_dblclick(o); });
+ this.acl_list.addEventListener('keypress', function(o) { rcmail.acl_list_keypress(o); });
+ this.acl_list.init();
+}
+
+// ACL table row selection handler
+rcube_webmail.prototype.acl_list_select = function(list)
+{
+ rcmail.enable_command('acl-delete', list.selection.length > 0);
+ rcmail.enable_command('acl-edit', list.selection.length == 1);
+ list.focus();
+}
+
+// ACL table double-click handler
+rcube_webmail.prototype.acl_list_dblclick = function(list)
+{
+ this.acl_edit();
+}
+
+// ACL table keypress handler
+rcube_webmail.prototype.acl_list_keypress = function(list)
+{
+ if (list.key_pressed == list.ENTER_KEY)
+ this.command('acl-edit');
+ else if (list.key_pressed == list.DELETE_KEY || list.key_pressed == list.BACKSPACE_KEY)
+ if (!this.acl_form || !this.acl_form.is(':visible'))
+ this.command('acl-delete');
+}
+
+// Reloads ACL table
+rcube_webmail.prototype.acl_list_update = function(html)
+{
+ $(this.gui_objects.acltable).html(html);
+ this.acl_list_init();
+}
+
+// Returns names of users in selected rows
+rcube_webmail.prototype.acl_get_usernames = function()
+{
+ var users = [], n, len, cell, row,
+ list = this.acl_list,
+ selection = list.get_selection();
+
+ for (n=0, len=selection.length; n<len; n++) {
+ if (this.env.acl_specials.length && $.inArray(selection[n], this.env.acl_specials) >= 0) {
+ users.push(selection[n]);
+ }
+ else {
+ row = list.rows[selection[n]].obj;
+ cell = $('td.user', row);
+ if (cell.length == 1)
+ users.push(cell.text());
+ }
+ }
+
+ return users;
+}
+
+// Removes ACL table row
+rcube_webmail.prototype.acl_remove_row = function(id)
+{
+ this.acl_list.remove_row(id);
+ // we don't need it anymore (remove id conflict)
+ $('#rcmrow'+id).remove();
+ this.env.acl[id] = null;
+}
+
+// Adds ACL table row
+rcube_webmail.prototype.acl_add_row = function(o, sel)
+{
+ var n, len, ids = [], spec = [], id = o.id, list = this.acl_list,
+ items = this.env.acl_advanced ? [] : this.env.acl_items,
+ table = this.gui_objects.acltable,
+ row = $('thead > tr', table).clone();
+
+ // Update new row
+ $('td', row).map(function() {
+ var r, cl = this.className.replace(/^acl/, '');
+
+ if (items && items[cl])
+ cl = items[cl];
+
+ if (cl == 'user')
+ $(this).text(o.username);
+ else
+ $(this).addClass(rcmail.acl_class(o.acl, cl)).text('');
+ });
+
+ row.attr('id', 'rcmrow'+id);
+ row = row.get(0);
+
+ this.env.acl[id] = o.acl;
+
+ // sorting... (create an array of user identifiers, then sort it)
+ for (n in this.env.acl) {
+ if (this.env.acl[n]) {
+ if (this.env.acl_specials.length && $.inArray(n, this.env.acl_specials) >= 0)
+ spec.push(n);
+ else
+ ids.push(n);
+ }
+ }
+ ids.sort();
+ // specials on the top
+ ids = spec.concat(ids);
+
+ // find current id
+ for (n=0, len=ids.length; n<len; n++)
+ if (ids[n] == id)
+ break;
+
+ // add row
+ if (n && n < len) {
+ $('#rcmrow'+ids[n-1]).after(row);
+ list.init_row(row);
+ list.rowcount++;
+ }
+ else
+ list.insert_row(row);
+
+ if (sel)
+ list.select_row(o.id);
+}
+
+// Initializes and shows ACL create/edit form
+rcube_webmail.prototype.acl_init_form = function(id)
+{
+ var ul, row, val = '', type = 'user', li_elements, body = $('body'),
+ adv_ul = $('#advancedrights'), sim_ul = $('#simplerights'),
+ name_input = $('#acluser');
+
+ if (!this.acl_form) {
+ var fn = function () { $('input[value=user]').prop('checked', true); };
+ name_input.click(fn).keypress(fn);
+ }
+
+ this.acl_form = $('#aclform');
+
+ // Hide unused items
+ if (this.env.acl_advanced) {
+ adv_ul.show();
+ sim_ul.hide();
+ ul = adv_ul;
+ }
+ else {
+ sim_ul.show();
+ adv_ul.hide();
+ ul = sim_ul;
+ }
+
+ // initialize form fields
+ li_elements = $(':checkbox', ul);
+ li_elements.attr('checked', false);
+
+ if (id) {
+ row = this.acl_list.rows[id].obj;
+ li_elements.map(function() {
+ var val = this.value, td = $('td.'+this.id, row);
+ if (td && td.hasClass('enabled'))
+ this.checked = true;
+ });
+
+ if (!this.env.acl_specials.length || $.inArray(id, this.env.acl_specials) < 0)
+ val = $('td.user', row).text();
+ else
+ type = id;
+ }
+
+ name_input.val(val);
+ $('input[value='+type+']').prop('checked', true);
+
+ this.acl_id = id;
+
+ // position the form horizontally
+ var bw = body.width(), mw = this.acl_form.width();
+
+ if (bw >= mw)
+ this.acl_form.css({left: parseInt((bw - mw)/2)+'px'});
+
+ // display it
+ this.acl_form.show();
+ if (type == 'user')
+ name_input.focus();
+
+ // unfocus the list, make backspace key in name input field working
+ this.acl_list.blur();
+}
+
+// Returns class name according to ACL comparision result
+rcube_webmail.prototype.acl_class = function(acl1, acl2)
+{
+ var i, len, found = 0;
+
+ acl1 = String(acl1);
+ acl2 = String(acl2);
+
+ for (i=0, len=acl2.length; i<len; i++)
+ if (acl1.indexOf(acl2[i]) > -1)
+ found++;
+
+ if (found == len)
+ return 'enabled';
+ else if (found)
+ return 'partial';
+
+ return 'disabled';
+}
View
701 plugins/acl/acl.php
@@ -0,0 +1,701 @@
+<?php
+
+/**
+ * Folders Access Control Lists Management (RFC4314, RFC2086)
+ *
+ * @version 0.6.2
+ * @author Aleksander Machniak <alec@alec.pl>
+ *
+ *
+ * Copyright (C) 2011, Kolab Systems AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+class acl extends rcube_plugin
+{
+ public $task = 'settings|addressbook|calendar';
+
+ private $rc;
+ private $supported = null;
+ private $mbox;
+ private $ldap;
+ private $specials = array('anyone', 'anonymous');
+
+ /**
+ * Plugin initialization
+ */
+ function init()
+ {
+ $this->rc = rcmail::get_instance();
+
+ // Register hooks
+ $this->add_hook('folder_form', array($this, 'folder_form'));
+ // kolab_addressbook plugin
+ $this->add_hook('addressbook_form', array($this, 'folder_form'));
+ $this->add_hook('calendar_form_kolab', array($this, 'folder_form'));
+ // Plugin actions
+ $this->register_action('plugin.acl', array($this, 'acl_actions'));
+ $this->register_action('plugin.acl-autocomplete', array($this, 'acl_autocomplete'));
+ }
+
+ /**
+ * Handler for plugin actions (AJAX)
+ */
+ function acl_actions()
+ {
+ $action = trim(get_input_value('_act', RCUBE_INPUT_GPC));
+
+ // Connect to IMAP
+ $this->rc->imap_init();
+ $this->rc->imap_connect();
+
+ // Load localization and configuration
+ $this->add_texts('localization/');
+ $this->load_config();
+
+ if ($action == 'save') {
+ $this->action_save();
+ }
+ else if ($action == 'delete') {
+ $this->action_delete();
+ }
+ else if ($action == 'list') {
+ $this->action_list();
+ }
+
+ // Only AJAX actions
+ $this->rc->output->send();
+ }
+
+ /**
+ * Handler for user login autocomplete request
+ */
+ function acl_autocomplete()
+ {
+ $this->load_config();
+
+ $search = get_input_value('_search', RCUBE_INPUT_GPC, true);
+ $sid = get_input_value('_id', RCUBE_INPUT_GPC);
+ $users = array();
+
+ if ($this->init_ldap()) {
+ $this->ldap->set_pagesize((int)$this->rc->config->get('autocomplete_max', 15));
+ $result = $this->ldap->search('*', $search);
+
+ foreach ($result->records as $record) {
+ $user = $record['uid'];
+
+ if (is_array($user)) {
+ $user = array_filter($user);
+ $user = $user[0];
+ }
+
+ if ($user) {
+ if ($record['name'])
+ $user = $record['name'] . ' (' . $user . ')';
+
+ $users[] = $user;
+ }
+ }
+ }
+
+ sort($users, SORT_LOCALE_STRING);
+
+ $this->rc->output->command('ksearch_query_results', $users, $search, $sid);
+ $this->rc->output->send();
+ }
+
+ /**
+ * Handler for 'folder_form' hook
+ *
+ * @param array $args Hook arguments array (form data)
+ *
+ * @return array Hook arguments array
+ */
+ function folder_form($args)
+ {
+ // Edited folder name (empty in create-folder mode)
+ $mbox_imap = $args['options']['name'];
+ if (!strlen($mbox_imap)) {
+ return $args;
+ }
+/*
+ // Do nothing on protected folders (?)
+ if ($args['options']['protected']) {
+ return $args;
+ }
+*/
+ // Namespace root
+ if ($args['options']['is_root']) {
+ return $args;
+ }
+
+ // Get MYRIGHTS
+ if (!($myrights = $args['options']['rights'])) {
+ return $args;
+ }
+
+ // Do nothing if no ACL support
+ if (!$this->rc->imap->get_capability('ACL')) {
+ return $args;
+ }
+
+ // Load localization and include scripts
+ $this->load_config();
+ $this->add_texts('localization/', array('deleteconfirm', 'norights',
+ 'nouser', 'deleting', 'saving'));
+ $this->include_script('acl.js');
+ $this->rc->output->include_script('list.js');
+ $this->include_stylesheet($this->local_skin_path().'/acl.css');
+
+ // add Info fieldset if it doesn't exist
+ if (!isset($args['form']['props']['fieldsets']['info']))
+ $args['form']['props']['fieldsets']['info'] = array(
+ 'name' => rcube_label('info'),
+ 'content' => array());
+
+ // Display folder rights to 'Info' fieldset
+ $args['form']['props']['fieldsets']['info']['content']['myrights'] = array(
+ 'label' => Q($this->gettext('myrights')),
+ 'value' => $this->acl2text($myrights)
+ );
+
+ // Return if not folder admin
+ if (!in_array('a', $myrights)) {
+ return $args;
+ }
+
+ // The 'Sharing' tab
+ $this->mbox = $mbox_imap;
+ $this->rc->output->set_env('acl_users_source', (bool) $this->rc->config->get('acl_users_source'));
+ $this->rc->output->set_env('mailbox', $mbox_imap);
+ $this->rc->output->add_handlers(array(
+ 'acltable' => array($this, 'templ_table'),
+ 'acluser' => array($this, 'templ_user'),
+ 'aclrights' => array($this, 'templ_rights'),
+ ));
+
+ $this->rc->output->set_env('autocomplete_max', (int)$this->rc->config->get('autocomplete_max', 15));
+ $this->rc->output->set_env('autocomplete_min_length', $this->rc->config->get('autocomplete_min_length'));
+ $this->rc->output->add_label('autocompletechars', 'autocompletemore');
+
+ $args['form']['sharing'] = array(
+ 'name' => Q($this->gettext('sharing')),
+ 'content' => $this->rc->output->parse('acl.table', false, false),
+ );
+
+ return $args;
+ }
+
+ /**
+ * Creates ACL rights table
+ *
+ * @param array $attrib Template object attributes
+ *
+ * @return string HTML Content
+ */
+ function templ_table($attrib)
+ {
+ if (empty($attrib['id']))
+ $attrib['id'] = 'acl-table';
+
+ $out = $this->list_rights($attrib);
+
+ $this->rc->output->add_gui_object('acltable', $attrib['id']);
+
+ return $out;
+ }
+
+ /**
+ * Creates ACL rights form (rights list part)
+ *
+ * @param array $attrib Template object attributes
+ *
+ * @return string HTML Content
+ */
+ function templ_rights($attrib)
+ {
+ // Get supported rights
+ $supported = $this->rights_supported();
+
+ // depending on server capability either use 'te' or 'd' for deleting msgs
+ $deleteright = implode(array_intersect(str_split('ted'), $supported));
+
+ $out = '';
+ $ul = '';
+ $input = new html_checkbox();
+
+ // Advanced rights
+ $attrib['id'] = 'advancedrights';
+ foreach ($supported as $val) {
+ $id = "acl$val";
+ $ul .= html::tag('li', null,
+ $input->show('', array(
+ 'name' => "acl[$val]", 'value' => $val, 'id' => $id))
+ . html::label(array('for' => $id, 'title' => $this->gettext('longacl'.$val)),
+ $this->gettext('acl'.$val)));
+ }
+
+ $out = html::tag('ul', $attrib, $ul, html::$common_attrib);
+
+ // Simple rights
+ $ul = '';
+ $attrib['id'] = 'simplerights';
+ $items = array(
+ 'read' => 'lrs',
+ 'write' => 'wi',
+ 'delete' => $deleteright,
+ 'other' => preg_replace('/[lrswi'.$deleteright.']/', '', implode($supported)),
+ );
+
+ foreach ($items as $key => $val) {
+ $id = "acl$key";
+ $ul .= html::tag('li', null,
+ $input->show('', array(
+ 'name' => "acl[$val]", 'value' => $val, 'id' => $id))
+ . html::label(array('for' => $id, 'title' => $this->gettext('longacl'.$key)),
+ $this->gettext('acl'.$key)));
+ }
+
+ $out .= "\n" . html::tag('ul', $attrib, $ul, html::$common_attrib);
+
+ $this->rc->output->set_env('acl_items', $items);
+
+ return $out;
+ }
+
+ /**
+ * Creates ACL rights form (user part)
+ *
+ * @param array $attrib Template object attributes
+ *
+ * @return string HTML Content
+ */
+ function templ_user($attrib)
+ {
+ // Create username input
+ $attrib['name'] = 'acluser';
+
+ $textfield = new html_inputfield($attrib);
+
+ $fields['user'] = html::label(array('for' => 'iduser'), $this->gettext('username'))
+ . ' ' . $textfield->show();
+
+ // Add special entries
+ if (!empty($this->specials)) {
+ foreach ($this->specials as $key) {
+ $fields[$key] = html::label(array('for' => 'id'.$key), $this->gettext($key));
+ }
+ }
+
+ $this->rc->output->set_env('acl_specials', $this->specials);
+
+ // Create list with radio buttons
+ if (count($fields) > 1) {
+ $ul = '';
+ $radio = new html_radiobutton(array('name' => 'usertype'));
+ foreach ($fields as $key => $val) {
+ $ul .= html::tag('li', null, $radio->show($key == 'user' ? 'user' : '',
+ array('value' => $key, 'id' => 'id'.$key))
+ . $val);
+ }
+
+ $out = html::tag('ul', array('id' => 'usertype'), $ul, html::$common_attrib);
+ }
+ // Display text input alone
+ else {
+ $out = $fields['user'];
+ }
+
+ return $out;
+ }
+
+ /**
+ * Creates ACL rights table
+ *
+ * @param array $attrib Template object attributes
+ *
+ * @return string HTML Content
+ */
+ private function list_rights($attrib=array())
+ {
+ // Get ACL for the folder
+ $acl = $this->rc->imap->get_acl($this->mbox);
+
+ if (!is_array($acl)) {
+ $acl = array();
+ }
+
+ // Keep special entries (anyone/anonymous) on top of the list
+ if (!empty($this->specials) && !empty($acl)) {
+ foreach ($this->specials as $key) {
+ if (isset($acl[$key])) {
+ $acl_special[$key] = $acl[$key];
+ unset($acl[$key]);
+ }
+ }
+ }
+
+ // Sort the list by username
+ uksort($acl, 'strnatcasecmp');
+
+ if (!empty($acl_special)) {
+ $acl = array_merge($acl_special, $acl);
+ }
+
+ // Get supported rights and build column names
+ $supported = $this->rights_supported();
+
+ // depending on server capability either use 'te' or 'd' for deleting msgs
+ $deleteright = implode(array_intersect(str_split('ted'), $supported));
+
+ // Use advanced or simple (grouped) rights
+ $advanced = $this->rc->config->get('acl_advanced_mode');
+
+ if ($advanced) {
+ $items = array();
+ foreach ($supported as $sup) {
+ $items[$sup] = $sup;
+ }
+ }
+ else {
+ $items = array(
+ 'read' => 'lrs',
+ 'write' => 'wi',
+ 'delete' => $deleteright,
+ 'other' => preg_replace('/[lrswi'.$deleteright.']/', '', implode($supported)),
+ );
+ }
+
+ // Create the table
+ $attrib['noheader'] = true;
+ $table = new html_table($attrib);
+
+ // Create table header
+ $table->add_header('user', $this->gettext('identifier'));
+ foreach (array_keys($items) as $key) {
+ $table->add_header('acl'.$key, $this->gettext('shortacl'.$key));
+ }
+
+ $i = 1;
+ $js_table = array();
+ foreach ($acl as $user => $rights) {
+ if ($this->rc->imap->conn->user == $user) {
+ continue;
+ }
+
+ // filter out virtual rights (c or d) the server may return
+ $userrights = array_intersect($rights, $supported);
+ $userid = html_identifier($user);
+
+ if (!empty($this->specials) && in_array($user, $this->specials)) {
+ $user = $this->gettext($user);
+ }
+
+ $table->add_row(array('id' => 'rcmrow'.$userid));
+ $table->add('user', Q($user));
+
+ foreach ($items as $key => $right) {
+ $in = $this->acl_compare($userrights, $right);
+ switch ($in) {
+ case 2: $class = 'enabled'; break;
+ case 1: $class = 'partial'; break;
+ default: $class = 'disabled'; break;
+ }
+ $table->add('acl' . $key . ' ' . $class, '');
+ }
+
+ $js_table[$userid] = implode($userrights);
+ }
+
+ $this->rc->output->set_env('acl', $js_table);
+ $this->rc->output->set_env('acl_advanced', $advanced);
+
+ $out = $table->show();
+
+ return $out;
+ }
+
+ /**
+ * Handler for ACL update/create action
+ */
+ private function action_save()
+ {
+ $mbox = trim(get_input_value('_mbox', RCUBE_INPUT_GPC, true)); // UTF7-IMAP
+ $user = trim(get_input_value('_user', RCUBE_INPUT_GPC));
+ $acl = trim(get_input_value('_acl', RCUBE_INPUT_GPC));
+ $oldid = trim(get_input_value('_old', RCUBE_INPUT_GPC));
+
+ $acl = array_intersect(str_split($acl), $this->rights_supported());
+
+ if (!empty($this->specials) && in_array($user, $this->specials)) {
+ $username = $this->gettext($user);
+ }
+ else {
+ if (!strpos($user, '@') && ($realm = $this->get_realm())) {
+ $user .= '@' . rcube_idn_to_ascii(preg_replace('/^@/', '', $realm));
+ }
+ $username = $user;
+ }
+
+ if ($acl && $user && $user != $_SESSION['username'] && strlen($mbox)) {
+ $result = $this->rc->imap->set_acl($mbox, $user, $acl);
+ }
+
+ if ($result) {
+ $ret = array('id' => html_identifier($user),
+ 'username' => $username, 'acl' => implode($acl), 'old' => $oldid);
+ $this->rc->output->command('acl_update', $ret);
+ $this->rc->output->show_message($oldid ? 'acl.updatesuccess' : 'acl.createsuccess', 'confirmation');
+ }
+ else {
+ $this->rc->output->show_message($oldid ? 'acl.updateerror' : 'acl.createerror', 'error');
+ }
+ }
+
+ /**
+ * Handler for ACL delete action
+ */
+ private function action_delete()
+ {
+ $mbox = trim(get_input_value('_mbox', RCUBE_INPUT_GPC, true)); //UTF7-IMAP
+ $user = trim(get_input_value('_user', RCUBE_INPUT_GPC));
+
+ $user = explode(',', $user);
+
+ foreach ($user as $u) {
+ if ($this->rc->imap->delete_acl($mbox, $u)) {
+ $this->rc->output->command('acl_remove_row', html_identifier($u));
+ }
+ else {
+ $error = true;
+ }
+ }
+
+ if (!$error) {
+ $this->rc->output->show_message('acl.deletesuccess', 'confirmation');
+ }
+ else {
+ $this->rc->output->show_message('acl.deleteerror', 'error');
+ }
+ }
+
+ /**
+ * Handler for ACL list update action (with display mode change)
+ */
+ private function action_list()
+ {
+ if (in_array('acl_advanced_mode', (array)$this->rc->config->get('dont_override'))) {
+ return;
+ }
+
+ $this->mbox = trim(get_input_value('_mbox', RCUBE_INPUT_GPC, true)); // UTF7-IMAP
+ $advanced = trim(get_input_value('_mode', RCUBE_INPUT_GPC));
+ $advanced = $advanced == 'advanced' ? true : false;
+
+ // Save state in user preferences
+ $this->rc->user->save_prefs(array('acl_advanced_mode' => $advanced));
+
+ $out = $this->list_rights();
+
+ $out = preg_replace(array('/^<table[^>]+>/', '/<\/table>$/'), '', $out);
+
+ $this->rc->output->command('acl_list_update', $out);
+ }
+
+ /**
+ * Creates <UL> list with descriptive access rights
+ *
+ * @param array $rights MYRIGHTS result
+ *
+ * @return string HTML content
+ */
+ function acl2text($rights)
+ {
+ if (empty($rights)) {
+ return '';
+ }
+
+ $supported = $this->rights_supported();
+ $list = array();
+ $attrib = array(
+ 'name' => 'rcmyrights',
+ 'style' => 'margin:0; padding:0 15px;',
+ );
+
+ foreach ($supported as $right) {
+ if (in_array($right, $rights)) {
+ $list[] = html::tag('li', null, Q($this->gettext('acl' . $right)));
+ }
+ }
+
+ if (count($list) == count($supported))
+ return Q($this->gettext('aclfull'));
+
+ return html::tag('ul', $attrib, implode("\n", $list));
+ }
+
+ /**
+ * Compares two ACLs (according to supported rights)
+ *
+ * @param array $acl1 ACL rights array (or string)
+ * @param array $acl2 ACL rights array (or string)
+ *
+ * @param int Comparision result, 2 - full match, 1 - partial match, 0 - no match
+ */
+ function acl_compare($acl1, $acl2)
+ {
+ if (!is_array($acl1)) $acl1 = str_split($acl1);
+ if (!is_array($acl2)) $acl2 = str_split($acl2);
+
+ $rights = $this->rights_supported();
+
+ $acl1 = array_intersect($acl1, $rights);
+ $acl2 = array_intersect($acl2, $rights);
+ $res = array_intersect($acl1, $acl2);
+
+ $cnt1 = count($res);
+ $cnt2 = count($acl2);
+
+ if ($cnt1 == $cnt2)
+ return 2;
+ else if ($cnt1)
+ return 1;
+ else
+ return 0;
+ }
+
+ /**
+ * Get list of supported access rights (according to RIGHTS capability)
+ *
+ * @return array List of supported access rights abbreviations
+ */
+ function rights_supported()
+ {
+ if ($this->supported !== null) {
+ return $this->supported;
+ }
+
+ $capa = $this->rc->imap->get_capability('RIGHTS');
+
+ if (is_array($capa)) {
+ $rights = strtolower($capa[0]);
+ }
+ else {
+ $rights = 'cd';
+ }
+
+ return $this->supported = str_split('lrswi' . $rights . 'pa');
+ }
+
+ /**
+ * Username realm detection.
+ *
+ * @return string Username realm (domain)
+ */
+ private function get_realm()
+ {
+ // When user enters a username without domain part, realm
+ // alows to add it to the username (and display correct username in the table)
+
+ if (isset($_SESSION['acl_username_realm'])) {
+ return $_SESSION['acl_username_realm'];
+ }
+
+ // find realm in username of logged user (?)
+ list($name, $domain) = explode('@', $_SESSION['username']);
+
+ // Use (always existent) ACL entry on the INBOX for the user to determine
+ // whether or not the user ID in ACL entries need to be qualified and how
+ // they would need to be qualified.
+ if (empty($domain)) {
+ $acl = $this->rc->imap->get_acl('INBOX');
+ if (is_array($acl)) {
+ $regexp = '/^' . preg_quote($_SESSION['username'], '/') . '@(.*)$/';
+ $regexp = '/^' . preg_quote('aleksander.machniak', '/') . '@(.*)$/';
+ foreach (array_keys($acl) as $name) {
+ if (preg_match($regexp, $name, $matches)) {
+ $domain = $matches[1];
+ break;
+ }
+ }
+ }
+ }
+
+ return $_SESSION['acl_username_realm'] = $domain;
+ }
+
+ /**
+ * Initializes autocomplete LDAP backend
+ */
+ private function init_ldap()
+ {
+ if ($this->ldap)
+ return $this->ldap->ready;
+
+ // get LDAP config
+ $config = $this->rc->config->get('acl_users_source');
+
+ if (empty($config)) {
+ return false;
+ }
+
+ // not an array, use configured ldap_public source
+ if (!is_array($config)) {
+ $ldap_config = (array) $this->rc->config->get('ldap_public');
+ $config = $ldap_config[$config];
+ }
+
+ $uid_field = $this->rc->config->get('acl_users_field', 'mail');
+ $filter = $this->rc->config->get('acl_users_filter');
+
+ if (empty($uid_field) || empty($config)) {
+ return false;
+ }
+
+ // get name attribute
+ if (!empty($config['fieldmap'])) {
+ $name_field = $config['fieldmap']['name'];
+ }
+ // ... no fieldmap, use the old method
+ if (empty($name_field)) {
+ $name_field = $config['name_field'];
+ }
+
+ // add UID field to fieldmap, so it will be returned in a record with name
+ $config['fieldmap'] = array(
+ 'name' => $name_field,
+ 'uid' => $uid_field,
+ );
+
+ // search in UID and name fields
+ $config['search_fields'] = array_values($config['fieldmap']);
+ $config['required_fields'] = array($uid_field);
+
+ // set search filter
+ if ($filter)
+ $config['filter'] = $filter;
+
+ // disable vlv
+ $config['vlv'] = false;
+
+ // Initialize LDAP connection
+ $this->ldap = new rcube_ldap($config,
+ $this->rc->config->get('ldap_debug'),
+ $this->rc->config->mail_domain($_SESSION['imap_host']));
+
+ return $this->ldap->ready;
+ }
+}
View
19 plugins/acl/config.inc.php.dist
@@ -0,0 +1,19 @@
+<?php
+
+// Default look of access rights table
+// In advanced mode all access rights are displayed separately
+// In simple mode access rights are grouped into four groups: read, write, delete, full
+$rcmail_config['acl_advanced_mode'] = false;
+
+// LDAP addressbook that would be searched for user names autocomplete.
+// That should be an array refering to the $rcmail_config['ldap_public'] array key
+// or complete addressbook configuration array.
+$rcmail_config['acl_users_source'] = '';
+
+// The LDAP attribute which will be used as ACL user identifier
+$rcmail_config['acl_users_field'] = 'mail';
+
+// The LDAP search filter will be &'d with search queries
+$rcmail_config['acl_users_filter'] = '';
+
+?>
View
83 plugins/acl/localization/de_DE.inc
@@ -0,0 +1,83 @@
+<?php
+
+$labels['sharing'] = 'Freigabe';
+$labels['myrights'] = 'Zugriffsrechte';
+$labels['username'] = 'Benutzer:';
+$labels['advanced'] = 'erweiterter Modus';
+$labels['newuser'] = 'Eintrag hinzufügen';
+$labels['actions'] = 'Zugriffsrechte Aktionen...';
+$labels['anyone'] = 'Alle Benutzer (anyone)';
+$labels['anonymous'] = 'Gäste (anonymous)';
+$labels['identifier'] = 'Bezeichnung';
+
+$labels['acll'] = 'Ordner sichtbar';
+$labels['aclr'] = 'Nachrichten lesen';
+$labels['acls'] = 'Lesestatus ändern';
+$labels['aclw'] = 'Flags schreiben';
+$labels['acli'] = 'Nachrichten Hinzufügen';
+$labels['aclp'] = 'Nachrichten Senden an';
+$labels['aclc'] = 'Unterordner erstellen';
+$labels['aclk'] = 'Unterordner erstellen';
+$labels['acld'] = 'Nachrichten als gelöscht markieren';
+$labels['aclt'] = 'Nachrichten als gelöscht markieren';
+$labels['acle'] = 'Nachrichten endgültig Löschen';
+$labels['aclx'] = 'Ordner löschen';
+$labels['acla'] = 'Zugriffsrechte Verwalten';
+
+$labels['aclfull'] = 'Vollzugriff';
+$labels['aclother'] = 'Andere';
+$labels['aclread'] = 'Lesen';
+$labels['aclwrite'] = 'Schreiben';
+$labels['acldelete'] = 'Löschen';
+
+$labels['shortacll'] = 'Sichtbar';
+$labels['shortaclr'] = 'Lesen';
+$labels['shortacls'] = 'Lesestatus';
+$labels['shortaclw'] = 'Flags ändern';
+$labels['shortacli'] = 'Hinzufügen';
+$labels['shortaclp'] = 'Senden an';
+$labels['shortaclc'] = 'Erstellen';
+$labels['shortaclk'] = 'Erstellen';
+$labels['shortacld'] = 'Löschen';
+$labels['shortaclt'] = 'Löschen';
+$labels['shortacle'] = 'endgültig löschen';
+$labels['shortaclx'] = 'Ordner löschen';
+$labels['shortacla'] = 'Verwalten';
+
+$labels['shortaclother'] = 'Andere';
+$labels['shortaclread'] = 'Lesen';
+$labels['shortaclwrite'] = 'Schreiben';
+$labels['shortacldelete'] = 'Löschen';
+
+$labels['longacll'] = 'Der Ordner ist sichtbar und kann abonniert werden';
+$labels['longaclr'] = 'Nachrichten im Ordner können gelesen werden';
+$labels['longacls'] = 'Der Lesestatus von Nachrichten kann geändert werden';
+$labels['longaclw'] = 'Alle Nachrichten-Flags und Schlüsselwörter außer "Gelesen" und "Gelöscht" können geändert werden';
+$labels['longacli'] = 'Nachrichten können in diesen Ordner kopiert oder verschoben werden';
+$labels['longaclp'] = 'Nachrichten können an diesen Ordner gesendet werden';
+$labels['longaclc'] = 'Unterordner können in diesem Ordner erstellt oder umbenannt werden';
+$labels['longaclk'] = 'Unterordner können in diesem Ordner erstellt oder umbenannt werden';
+$labels['longacld'] = 'Der "gelöscht" Status von Nachrichten kann geändert werden';
+$labels['longaclt'] = 'Der "gelöscht" Status von Nachrichten kann geändert werden';
+$labels['longacle'] = 'Als "gelöscht" markiert Nachrichten können gelöscht werden.';
+$labels['longaclx'] = 'Der Ordner kann gelöscht oder umbenannt werden';
+$labels['longacla'] = 'Die Zugriffsrechte des Ordners können geändert werden';
+
+$labels['longaclfull'] = 'Vollzugriff inklusive Ordner-Verwaltung';
+$labels['longaclread'] = 'Der Ordnerinhalt kann gelesen werden';
+$labels['longaclwrite'] = 'Nachrichten können markiert, an den Ordner gesendet und in den Ordner kopiert oder verschoben werden';
+$labels['longacldelete'] = 'Nachrichten können gelöscht werden';
+
+$messages['deleting'] = 'Zugriffsrechte werden entzogen...';
+$messages['saving'] = 'Zugriffsrechte werden gewährt...';
+$messages['updatesuccess'] = 'Zugriffsrechte erfolgreich geändert';
+$messages['deletesuccess'] = 'Zugriffsrechte erfolgreich entzogen';
+$messages['createsuccess'] = 'Zugriffsrechte erfolgreich gewährt';
+$messages['updateerror'] = 'Zugriffsrechte konnten nicht geändert werden';
+$messages['deleteerror'] = 'Zugriffsrechte konnten nicht entzogen werden';
+$messages['createerror'] = 'Zugriffsrechte konnten nicht gewährt werden';
+$messages['deleteconfirm'] = 'Sind Sie sicher, daß Sie die Zugriffsrechte den ausgewählten Benutzern entziehen möchten?';
+$messages['norights'] = 'Es wurden keine Zugriffsrechte ausgewählt!';
+$messages['nouser'] = 'Es wurde kein Benutzer ausgewählt!';
+
+?>
View
83 plugins/acl/localization/en_US.inc
@@ -0,0 +1,83 @@
+<?php
+
+$labels['sharing'] = 'Sharing';
+$labels['myrights'] = 'Access Rights';
+$labels['username'] = 'User:';
+$labels['advanced'] = 'advanced mode';
+$labels['newuser'] = 'Add entry';
+$labels['actions'] = 'Access right actions...';
+$labels['anyone'] = 'All users (anyone)';
+$labels['anonymous'] = 'Guests (anonymous)';
+$labels['identifier'] = 'Identifier';
+
+$labels['acll'] = 'Lookup';
+$labels['aclr'] = 'Read messages';
+$labels['acls'] = 'Keep Seen state';
+$labels['aclw'] = 'Write flags';
+$labels['acli'] = 'Insert (Copy into)';
+$labels['aclp'] = 'Post';
+$labels['aclc'] = 'Create subfolders';
+$labels['aclk'] = 'Create subfolders';
+$labels['acld'] = 'Delete messages';
+$labels['aclt'] = 'Delete messages';
+$labels['acle'] = 'Expunge';
+$labels['aclx'] = 'Delete folder';
+$labels['acla'] = 'Administer';
+
+$labels['aclfull'] = 'Full control';
+$labels['aclother'] = 'Other';
+$labels['aclread'] = 'Read';
+$labels['aclwrite'] = 'Write';
+$labels['acldelete'] = 'Delete';
+
+$labels['shortacll'] = 'Lookup';
+$labels['shortaclr'] = 'Read';
+$labels['shortacls'] = 'Keep';
+$labels['shortaclw'] = 'Write';
+$labels['shortacli'] = 'Insert';
+$labels['shortaclp'] = 'Post';
+$labels['shortaclc'] = 'Create';
+$labels['shortaclk'] = 'Create';
+$labels['shortacld'] = 'Delete';
+$labels['shortaclt'] = 'Delete';
+$labels['shortacle'] = 'Expunge';
+$labels['shortaclx'] = 'Folder delete';
+$labels['shortacla'] = 'Administer';
+
+$labels['shortaclother'] = 'Other';
+$labels['shortaclread'] = 'Read';
+$labels['shortaclwrite'] = 'Write';
+$labels['shortacldelete'] = 'Delete';
+
+$labels['longacll'] = 'The folder is visible on lists and can be subscribed to';
+$labels['longaclr'] = 'The folder can be opened for reading';
+$labels['longacls'] = 'Messages Seen flag can be changed';
+$labels['longaclw'] = 'Messages flags and keywords can be changed, except Seen and Deleted';
+$labels['longacli'] = 'Messages can be written or copied to the folder';
+$labels['longaclp'] = 'Messages can be posted to this folder';
+$labels['longaclc'] = 'Folders can be created (or renamed) directly under this folder';
+$labels['longaclk'] = 'Folders can be created (or renamed) directly under this folder';
+$labels['longacld'] = 'Messages Delete flag can be changed';
+$labels['longaclt'] = 'Messages Delete flag can be changed';
+$labels['longacle'] = 'Messages can be expunged';
+$labels['longaclx'] = 'The folder can be deleted or renamed';
+$labels['longacla'] = 'The folder access rights can be changed';
+
+$labels['longaclfull'] = 'Full control including folder administration';
+$labels['longaclread'] = 'The folder can be opened for reading';
+$labels['longaclwrite'] = 'Messages can be marked, written or copied to the folder';
+$labels['longacldelete'] = 'Messages can be deleted';
+
+$messages['deleting'] = 'Deleting access rights...';
+$messages['saving'] = 'Saving access rights...';
+$messages['updatesuccess'] = 'Successfully changed access rights';
+$messages['deletesuccess'] = 'Successfully deleted access rights';
+$messages['createsuccess'] = 'Successfully added access rights';
+$messages['updateerror'] = 'Ubable to update access rights';
+$messages['deleteerror'] = 'Unable to delete access rights';
+$messages['createerror'] = 'Unable to add access rights';
+$messages['deleteconfirm'] = 'Are you sure, you want to remove access rights of selected user(s)?';
+$messages['norights'] = 'No rights has been specified!';
+$messages['nouser'] = 'No username has been specified!';
+
+?>
View
83 plugins/acl/localization/pl_PL.inc
@@ -0,0 +1,83 @@
+<?php
+
+$labels['sharing'] = 'Udostępnianie';
+$labels['myrights'] = 'Prawa dostępu';
+$labels['username'] = 'Użytkownik:';
+$labels['advanced'] = 'tryb zaawansowany';
+$labels['newuser'] = 'Dodaj rekord';
+$labels['actions'] = 'Akcje na prawach...';
+$labels['anyone'] = 'Wszyscy (anyone)';
+$labels['anonymous'] = 'Goście (anonymous)';
+$labels['identifier'] = 'Identyfikator';
+
+$labels['acll'] = 'Podgląd (Lookup)';
+$labels['aclr'] = 'Odczyt (Read)';
+$labels['acls'] = 'Zmiana stanu wiadomości (Keep)';
+$labels['aclw'] = 'Zmiana flag wiadomości (Write)';
+$labels['acli'] = 'Dodawanie/Kopiowanie do (Insert)';
+$labels['aclp'] = 'Wysyłanie (Post)';
+$labels['aclc'] = 'Tworzenie podfolderów (Create)';
+$labels['aclk'] = 'Tworzenie podfolderów (Create)';
+$labels['acld'] = 'Usuwanie wiadomości (Delete)';
+$labels['aclt'] = 'Usuwanie wiadomości (Delete)';
+$labels['acle'] = 'Porządkowanie folderu (Expunge)';
+$labels['aclx'] = 'Usuwanie folderu (Delete)';
+$labels['acla'] = 'Administracja (Administer)';
+
+$labels['aclfull'] = 'Wszystkie';
+$labels['aclother'] = 'Inne';
+$labels['aclread'] = 'Odczyt';
+$labels['aclwrite'] = 'Zapis';
+$labels['acldelete'] = 'Usuwanie';
+
+$labels['shortacll'] = 'Podgląd';
+$labels['shortaclr'] = 'Odczyt';
+$labels['shortacls'] = 'Zmiana';
+$labels['shortaclw'] = 'Zmiana flag';
+$labels['shortacli'] = 'Dodawanie';
+$labels['shortaclp'] = 'Wysyłanie';
+$labels['shortaclc'] = 'Tworzenie';
+$labels['shortaclk'] = 'Tworzenie';
+$labels['shortacld'] = 'Usuwanie';
+$labels['shortaclt'] = 'Usuwanie';
+$labels['shortacle'] = 'Porządkowanie';
+$labels['shortaclx'] = 'Usuwanie folderu';
+$labels['shortacla'] = 'Administracja';
+
+$labels['shortaclother'] = 'Pozostałe';
+$labels['shortaclread'] = 'Odczyt';
+$labels['shortaclwrite'] = 'Zapis';
+$labels['shortacldelete'] = 'Usuwanie';
+
+$labels['longacll'] = 'Pozwala na subskrybowanie folderu i powoduje, że jest on widoczny na liście';
+$labels['longaclr'] = 'Pozwala na otwarcie folderu w trybie do odczytu';
+$labels['longacls'] = 'Pozwala na zmienę stanu wiadomości';
+$labels['longaclw'] = 'Pozwala zmieniać wszystkie flagi wiadomości, oprócz "Przeczytano" i "Usunięto"';
+$labels['longacli'] = 'Pozwala zapisywać wiadomości i kopiować do folderu';
+$labels['longaclp'] = 'Pozwala wysyłać wiadomości do folderu';
+$labels['longaclc'] = 'Pozwala tworzyć (lub zmieniać nazwę) podfoldery';
+$labels['longaclk'] = 'Pozwala tworzyć (lub zmieniać nazwę) podfoldery';
+$labels['longacld'] = 'Pozwala zmianiać flagę "Usunięto" wiadomości';
+$labels['longaclt'] = 'Pozwala zmianiać flagę "Usunięto" wiadomości';
+$labels['longacle'] = 'Pozwala na usuwanie wiadomości oznaczonych do usunięcia';
+$labels['longaclx'] = 'Pozwala na zmianę nazwy lub usunięcie folderu';
+$labels['longacla'] = 'Pozwala na zmiane praw dostępu do folderu';
+
+$labels['longaclfull'] = 'Pełna kontrola włącznie z administrowaniem folderem';
+$labels['longaclread'] = 'Folder może być otwarty w trybie do odczytu';
+$labels['longaclwrite'] = 'Wiadomości mogą być oznaczane, zapisywane i kopiowane do folderu';
+$labels['longacldelete'] = 'Wiadomości mogą być usuwane';
+
+$messages['deleting'] = 'Usuwanie praw dostępu...';
+$messages['saving'] = 'Zapisywanie praw dostępu...';
+$messages['updatesuccess'] = 'Pomyślnie zmieniono prawa dostępu';
+$messages['deletesuccess'] = 'Pomyślnie usunięto prawa dostępu';
+$messages['createsuccess'] = 'Pomyślnie dodano prawa dostępu';
+$messages['updateerror'] = 'Nie udało się zmienić praw dostępu';
+$messages['deleteerror'] = 'Nie udało się usunąć praw dostępu';
+$messages['createerror'] = 'Nie udało się dodać praw dostępu';
+$messages['deleteconfirm'] = 'Czy na pewno chcesz usunąć prawa wybranym użytkownikom?';
+$messages['norights'] = 'Nie wybrano praw dostępu!';
+$messages['nouser'] = 'Nie podano nazwy użytkownika!';
+
+?>
View
100 plugins/acl/skins/default/acl.css
@@ -0,0 +1,100 @@
+#aclmanager
+{
+ position: relative;
+ border: 1px solid #999;
+ min-height: 302px;
+}
+
+#aclcontainer
+{
+ overflow-x: auto;
+}
+
+#acltable
+{
+ width: 100%;
+ border-collapse: collapse;
+ background-color: #F9F9F9;
+}
+
+#acltable td
+{
+ width: 1%;
+ white-space: nowrap;
+}
+
+#acltable thead td
+{
+ padding: 0 4px 0 2px;
+}
+
+#acltable tbody td
+{
+ text-align: center;
+ padding: 2px;
+ border-bottom: 1px solid #999999;
+ cursor: default;
+}
+
+#acltable tbody td.user
+{
+ width: 96%;
+ text-align: left;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ -o-text-overflow: ellipsis;
+}
+
+#acltable tbody td.partial
+{
+ background: url(images/partial.png) center no-repeat;
+}
+
+#acltable tbody td.enabled
+{
+ background: url(images/enabled.png) center no-repeat;
+}
+
+#acltable tr.selected td
+{
+ color: #FFFFFF;
+ background-color: #CC3333;
+}
+
+#acltable tr.unfocused td
+{
+ color: #FFFFFF;
+ background-color: #929292;
+}
+
+#acladvswitch
+{
+ position: absolute;
+ right: 4px;
+ text-align: right;
+ line-height: 22px;
+}
+
+#acladvswitch input
+{
+ vertical-align: middle;
+}
+
+#acladvswitch span
+{
+ display: block;
+}
+
+#aclform
+{
+ top: 80px;
+ width: 480px;
+ padding: 10px;
+}
+
+#aclform div
+{
+ padding: 0;
+ text-align: center;
+ clear: both;
+}
View
BIN  plugins/acl/skins/default/images/enabled.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  plugins/acl/skins/default/images/partial.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
54 plugins/acl/skins/default/templates/table.html
@@ -0,0 +1,54 @@
+<!--[if lte IE 6]>
+ <style type="text/css">
+ #aclmanager { height: expression(Math.min(302, parseInt(document.documentElement.clientHeight))+'px'); }
+ </style>
+<![endif]-->
+
+<div id="aclmanager">
+<div id="aclcontainer" class="boxlistcontent" style="top:0">
+ <roundcube:object name="acltable" id="acltable" class="records-table" />
+</div>
+<div class="boxfooter">
+ <roundcube:button command="acl-create" id="aclcreatelink" type="link" title="acl.newuser" class="buttonPas addgroup" classAct="button addgroup" content=" " />
+ <roundcube:button name="aclmenulink" id="aclmenulink" type="link" title="acl.actions" class="button groupactions" onclick="show_aclmenu(); return false" content=" " />
+ <roundcube:if condition="!in_array('acl_advanced_mode', (array)config:dont_override)" />
+ <div id="acladvswitch" class="pagenav">
+ <span><label for="acl-switch"><roundcube:label name="acl.advanced" /></label>
+ <input type="checkbox" id="acl-switch" onclick="rcmail.command('acl-mode-switch')"<roundcube:exp expression="config:acl_advanced_mode == true ? ' checked=checked' : ''" /> />
+ </span>
+ </div>
+ <roundcube:endif />
+</div>
+</div>
+
+<div id="aclmenu" class="popupmenu">
+ <ul>
+ <li><roundcube:button command="acl-edit" label="edit" classAct="active" /></li>
+ <li><roundcube:button command="acl-delete" label="delete" classAct="active" /></li>
+ </ul>
+</div>
+
+<div id="aclform" class="popupmenu">
+ <fieldset class="thinbordered"><legend><roundcube:label name="acl.identifier" /></legend>
+ <roundcube:object name="acluser" class="toolbarmenu" id="acluser" size="35" />
+ </fieldset>
+ <fieldset class="thinbordered"><legend><roundcube:label name="acl.myrights" /></legend>
+ <roundcube:object name="aclrights" class="toolbarmenu" />
+ </fieldset>
+ <div>
+ <roundcube:button command="acl-cancel" type="input" class="button" label="cancel" />
+ <roundcube:button command="acl-save" type="input" class="button mainaction" label="save" />
+ </div>
+</div>
+
+<script type="text/javascript">
+function show_aclmenu()
+{
+ if (!rcmail_ui) {
+ rcube_init_mail_ui();
+ rcmail_ui.popups.aclmenu = {id:'aclmenu', above:1, obj: $('#aclmenu')};
+ }
+
+ rcmail_ui.show_popup('aclmenu');
+}
+</script>
View
43 plugins/additional_message_headers/additional_message_headers.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * Additional Message Headers
+ *
+ * Very simple plugin which will add additional headers
+ * to or remove them from outgoing messages.
+ *
+ * Enable the plugin in config/main.inc.php and add your desired headers:
+ * $rcmail_config['additional_message_headers'] = array('User-Agent');
+ *
+ * @version @package_version@
+ * @author Ziba Scott
+ * @website http://roundcube.net
+ */
+class additional_message_headers extends rcube_plugin
+{
+ public $task = 'mail';
+
+ function init()
+ {
+ $this->add_hook('message_outgoing_headers', array($this, 'message_headers'));
+ }
+
+ function message_headers($args)
+ {
+ $this->load_config();
+
+ // additional email headers
+ $additional_headers = rcmail::get_instance()->config->get('additional_message_headers',array());
+ foreach($additional_headers as $header=>$value){
+ if (null === $value) {
+ unset($args['headers'][$header]);
+ } else {
+ $args['headers'][$header] = $value;
+ }
+ }
+
+ return $args;
+ }
+}
+
+?>
View
14 plugins/additional_message_headers/config.inc.php.dist
@@ -0,0 +1,14 @@
+<?php
+
+// $rcmail_config['additional_message_headers']['X-Remote-Browser'] = $_SERVER['HTTP_USER_AGENT'];
+// $rcmail_config['additional_message_headers']['X-Originating-IP'] = $_SERVER['REMOTE_ADDR'];
+// $rcmail_config['additional_message_headers']['X-RoundCube-Server'] = $_SERVER['SERVER_ADDR'];
+
+// if( isset( $_SERVER['MACHINE_NAME'] )) {
+// $rcmail_config['additional_message_headers']['X-RoundCube-Server'] .= ' (' . $_SERVER['MACHINE_NAME'] . ')';
+// }
+
+// To remove (e.g. X-Sender) message header use null value
+// $rcmail_config['additional_message_headers']['X-Sender'] = null;
+
+?>
View
47 plugins/additional_message_headers/package.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.9.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>additional_message_headers</name>
+ <channel>pear.roundcube.net</channel>
+ <summary>Additional message headers for Roundcube</summary>
+ <description>Very simple plugin which will add additional headers to or remove them from outgoing messages.</description>
+ <lead>
+ <name>Ziba Scott</name>
+ <user>ziba</user>
+ <email>email@example.org</email>
+ <active>yes</active>
+ </lead>
+ <date>2010-01-16</date>
+ <time>18:19:33</time>
+ <version>
+ <release>1.1.0</release>
+ <api>1.1.0</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPL v2</license>
+ <notes>-</notes>
+ <contents>
+ <dir baseinstalldir="/" name="/">
+ <file name="additional_message_headers.php" role="php">
+ <tasks:replace from="@name@" to="name" type="package-info" />
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ </dir> <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.1</min>
+ </php>
+ <pearinstaller>
+ <min>1.7.0</min>
+ </pearinstaller>
+ </required>
+ </dependencies>
+ <phprelease />
+</package>
View
34 plugins/archive/archive.js
@@ -0,0 +1,34 @@
+/*
+ * Archive plugin script
+ * @version @package_version@
+ */
+
+function rcmail_archive(prop)
+{
+ if (!rcmail.env.uid && (!rcmail.message_list || !rcmail.message_list.get_selection().length))
+ return;
+
+ if (rcmail.env.mailbox != rcmail.env.archive_folder)
+ rcmail.command('moveto', rcmail.env.archive_folder);
+}
+
+// callback for app-onload event
+if (window.rcmail) {
+ rcmail.addEventListener('init', function(evt) {
+
+ // register command (directly enable in message view mode)
+ rcmail.register_command('plugin.archive', rcmail_archive, (rcmail.env.uid && rcmail.env.mailbox != rcmail.env.archive_folder));
+
+ // add event-listener to message list
+ if (rcmail.message_list)
+ rcmail.message_list.addEventListener('select', function(list){
+ rcmail.enable_command('plugin.archive', (list.get_selection().length > 0 && rcmail.env.mailbox != rcmail.env.archive_folder));
+ });
+
+ // set css style for archive folder
+ var li;
+ if (rcmail.env.archive_folder && rcmail.env.archive_folder_icon && (li = rcmail.get_folder_li(rcmail.env.archive_folder)))
+ $(li).css('background-image', 'url(' + rcmail.env.archive_folder_icon + ')');
+ })
+}
+
View
124 plugins/archive/archive.php
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * Archive
+ *
+ * Plugin that adds a new button to the mailbox toolbar
+ * to move messages to a (user selectable) archive folder.
+ *
+ * @version @package_version@
+ * @author Andre Rodier, Thomas Bruederli
+ */
+class archive extends rcube_plugin
+{
+ public $task = 'mail|settings';
+
+ function init()
+ {
+ $rcmail = rcmail::get_instance();