oddmuse-quickstart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. #!/bin/bash
  2. # Copyright (C) 2015 Alex-Daniel Jakimenko <alex.jakimenko@gmail.com>
  3. #
  4. # This program is free software: you can redistribute it and/or modify it under
  5. # the terms of the GNU General Public License as published by the Free Software
  6. # Foundation, either version 3 of the License, or (at your option) any later
  7. # version.
  8. #
  9. # This program is distributed in the hope that it will be useful, but WITHOUT
  10. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License along with
  14. # this program. If not, see <http://www.gnu.org/licenses/>.
  15. set -e # fatal errors
  16. REPO_LINK='https://raw.githubusercontent.com/kensanata/oddmuse/2.3.5/'
  17. exit_reason=''
  18. # We will use alternating colors so that it is easier to see which part
  19. # was just printed. Otherwise it is pretty hard to use.
  20. color1=$(tput setaf 4)
  21. color2=$(tput setaf 6)
  22. colorHeading=$(tput setaf 2)
  23. colorNone=$(tput sgr0)
  24. prompt() {
  25. local answer prompt default
  26. if [[ ! $2 || ${2^} = Y* ]]; then
  27. prompt='Y/n'
  28. default='Y'
  29. elif [[ ${2^} = N* ]]; then
  30. prompt='y/N'
  31. default='N'
  32. fi
  33. while :; do
  34. if [[ $curColor == "$color2" ]]; then # TODO more colors?
  35. curColor=$color1
  36. else
  37. curColor=$color2
  38. fi
  39. read -r -p "$curColor$1$colorNone [$prompt] " answer
  40. [[ ! $answer ]] && answer=$default
  41. if [[ ${answer^} = Y* ]]; then
  42. echo
  43. return 0
  44. fi
  45. if [[ ${answer^} = N* ]]; then
  46. echo
  47. return 1
  48. fi
  49. done
  50. }
  51. err() {
  52. printf "%s\n" "$1"
  53. exit_reason='err'
  54. exit
  55. }
  56. clean() {
  57. case $exit_reason in
  58. ok)
  59. echo 'Good luck! (:'
  60. exit 0;
  61. ;;
  62. quit)
  63. echo 'You have aborted this script.'
  64. exit 1
  65. ;;
  66. *)
  67. echo 'This script terminated unexpectedly. :('
  68. exit 1
  69. esac
  70. }
  71. trap clean EXIT
  72. echo "==$colorHeading Welcome! $colorNone=="
  73. echo 'This script will guide you through the process of **setting up a new** Oddmuse wiki.'
  74. echo 'It will also attempt to explain every step.'
  75. echo
  76. echo 'Every step will ask your confirmation. It will look like "[Y/n]".'
  77. echo 'Enter "y" (yes) or "n" (no) to answer the question.'
  78. echo 'Uppercase letter means that this action is the default and you can just press Enter.'
  79. echo
  80. echo 'At any moment you can press Ctrl-C to abort the process.'
  81. echo
  82. echo "==$colorHeading Main script $colorNone=="
  83. echo 'First of all, we have to download the main script and put it into ##cgi-bin## directory.'
  84. if [[ ! -d 'cgi-bin' ]]; then
  85. echo
  86. echo 'It seems like your ##cgi-bin## directory is missing.'
  87. echo
  88. if ! prompt 'Do you want to create cgi-bin now?' Y; then
  89. echo 'You decided not to create ##cgi-bin## folder.'
  90. echo 'This script was meant for simple setups with cgi-bin folder.'
  91. echo 'See https://oddmuse.org/wiki/Setup for manual installation instructions.'
  92. exit_reason='quit'
  93. exit
  94. fi
  95. mkdir -- 'cgi-bin' || err 'Cannot create cgi-bin directory. This may be caused by the lack of permissions.'
  96. echo '* ##cgi-bin## directory was created.'
  97. chmod 755 -- 'cgi-bin'
  98. echo '* ##cgi-bin## permissions were set to 755 (rwxr-xr-x).'
  99. cat <<'EOF' > 'cgi-bin/.htaccess'
  100. Options +ExecCGI
  101. SetHandler cgi-script
  102. EOF
  103. echo '* ##cgi-bin/.htaccess## file was created with these contents:'
  104. echo '{{{'
  105. cat 'cgi-bin/.htaccess'
  106. echo '}}}'
  107. fi
  108. echo
  109. if ! prompt 'Download wiki.pl right now?' Y; then
  110. echo 'You have decided not to download the script, but you cannot use Oddmuse without downloading it first.'
  111. echo
  112. echo 'See https://oddmuse.org/wiki/Setup for manual installation instructions.'
  113. exit
  114. fi
  115. wget -nv -O cgi-bin/wiki.pl "$REPO_LINK/wiki.pl" || err 'Cannot download the main script (wiki.pl).'
  116. echo
  117. echo '* ##wiki.pl## was successfully downloaded into your ##cgi-bin## directory.'
  118. chmod +x 'cgi-bin/wiki.pl'
  119. echo '* ##cgi-bin/wiki.pl## file is now executable.'
  120. echo
  121. echo "==$colorHeading Data directory $colorNone=="
  122. echo 'You have to specify some location for permanent data storage.'
  123. echo
  124. echo 'If you wont do that, the wiki will run in **temporary mode**.'
  125. echo
  126. echo 'In temporary mode, any change is stored in /tmp (and therefore will be eventually deleted).'
  127. echo
  128. echo 'In order to keep the data you must specify ##$DataDir##.'
  129. echo
  130. echo 'The easiest way to do that is to set ##WikiDataDir## environment variable in ##.htaccess##.'
  131. echo
  132. echo 'This will be appended to your ##.htaccess## file:'
  133. echo '{{{'
  134. echo 'SetEnv WikiDataDir ../wiki'
  135. echo '}}}'
  136. echo
  137. if ! prompt 'Set WikiDataDir environment variable?' Y; then
  138. echo 'You have decided not to use WikiDataDir environment variable.'
  139. echo
  140. echo 'This means that you have to use a wrapper script instead.'
  141. echo
  142. echo 'See https://oddmuse.org/wiki/Setup for more instructions.'
  143. exit
  144. fi
  145. echo >> '.htaccess'
  146. echo 'SetEnv WikiDataDir ../wiki' >> '.htaccess'
  147. echo '* WikiDataDir variable is now conigured to ##../wiki## (relative to ##cgi-bin## directory).'
  148. echo
  149. echo "==$colorHeading Basic setup $colorNone=="
  150. echo
  151. if [[ ! -d 'wiki/' ]]; then
  152. echo "===$colorHeading wiki/ $colorNone==="
  153. echo '##wiki/## directory will contain all data associated with your wiki, that is:'
  154. echo '* Pages and kept pages (previous versions)'
  155. echo '* Modules (also called Extensions)'
  156. echo '* Temp files and logs'
  157. echo '* And some other less relevant stuff'
  158. echo
  159. prompt 'Create ##wiki/## directory?' Y
  160. mkdir 'wiki'
  161. echo '##wiki/## directory was created.'
  162. echo
  163. fi
  164. if [[ ! -d 'wiki/modules/' ]]; then
  165. echo "===$colorHeading wiki/modules/ $colorNone==="
  166. echo '##wiki/modules/## can contain perl files that extend the functionality of the core.'
  167. echo 'These could be your own modules, or one of the 200+ contributed modules.'
  168. echo 'You can see a structured list of modules on https://oddmuse.org/wiki/Site_Map'
  169. echo
  170. prompt 'Create ##wiki/modules## directory?' Y
  171. mkdir 'wiki/modules'
  172. echo '##wiki/modules/## directory was created.'
  173. echo
  174. fi
  175. if [[ ! -f 'wiki/config' ]]; then
  176. echo "===$colorHeading wiki/config $colorNone==="
  177. default_config=$'use utf8; # allow utf-8 characters in config file\n'
  178. echo '##wiki/config## can contain perl code that will be ran during the core initialization on each request.'
  179. echo
  180. echo 'Config file will be initialized in ##wiki/config## with these contents:'
  181. echo '{{{'
  182. echo "$default_config"
  183. echo '}}}'
  184. echo
  185. prompt 'Initialize config file?' Y
  186. printf "%s\n" "$default_config" >> 'wiki/config'
  187. echo 'Config file was initialized.'
  188. echo
  189. fi
  190. if [[ ! -f '.htaccess' ]]; then
  191. main_htaccess='# Do not let people see your directory structure
  192. Options -Indexes
  193. # Make your wiki accessible with just /SomePage instead of /cgi-bin/run.pl/SomePage
  194. RewriteEngine On
  195. RewriteRule ^([^/]*)$ /cgi-bin/run.pl/$1 [QSA,L]
  196. RewriteRule ^$ cgi-bin/run.pl [QSA,L,PT]'
  197. echo "===$colorHeading .htaccess $colorNone==="
  198. echo '##.htaccess## is a configuration file that is used by several web servers (e.g. Apache).'
  199. echo '##.htaccess## file will be created with these contents:'
  200. echo '{{{'
  201. echo "$main_htaccess"
  202. echo '}}}'
  203. echo
  204. prompt 'Create ##.htaccess## file?' Y
  205. printf "%s\n" "$main_htaccess" >> '.htaccess'
  206. echo '##.htaccess## was created.'
  207. echo
  208. fi
  209. if [[ ! -f 'wiki/.htaccess' ]]; then
  210. wiki_htaccess='# Hide this directory from world
  211. Deny from all'
  212. echo "===$colorHeading wiki/.htaccess $colorNone==="
  213. echo 'We have to hide files in ##wiki/## from public.'
  214. echo '##wiki/.htaccess## file be created with these contents:'
  215. echo '{{{'
  216. echo "$wiki_htaccess"
  217. echo '}}}'
  218. echo
  219. prompt 'Create ##wiki/.htaccess## file?' Y
  220. printf "%s\n" "$wiki_htaccess" >> 'wiki/.htaccess'
  221. echo '##wiki/.htaccess## was created.'
  222. echo
  223. fi
  224. echo "==$colorHeading Config file $colorNone=="
  225. echo 'Now we will do a couple of modifications to the ##wiki/config## file.'
  226. echo
  227. echo 'Config file is just a perl script that is ran by the core during initialization.'
  228. echo
  229. echo 'Feel free to edit it yourself manually at any time!'
  230. echo
  231. echo "===$colorHeading Password $colorNone==="
  232. echo 'It is a good idea to have administrator password set.'
  233. echo
  234. echo 'This script will hash your salted password with sha256 and then it'
  235. echo 'will save that hash in your config file.'
  236. echo
  237. echo 'Although salt is used, it is still easy to bruteforce sha256 hashes.'
  238. echo 'If you think that bcrypt is a better option, you can change your config file later.'
  239. echo
  240. echo 'Please use a strong password (we will let you decide yourself which'
  241. echo 'password is strong enough, you can use any characters).'
  242. echo
  243. prompt 'Do you want to set your password now?' Y
  244. echo '//You will not see what you are typing, this is OK.//'
  245. read -rs -p "Password:" password
  246. echo
  247. echo
  248. password_config='use Digest::SHA qw(sha256_hex);
  249. $PassHashFunction = \&sha256_hex;
  250. '
  251. salt=$(head -c 32 /dev/urandom | xxd -p -c 32) # urandom is OK for generating random strings
  252. password_config+="\$PassSalt = '$salt'; # random salt. Generated with: head -c 32 /dev/urandom | xxd -p -c 32"$'\n'
  253. password_config+="\$AdminPass = '$(printf "%s" "$password$salt" | sha256sum | cut -d ' ' -f 1)'"'; # Generated with: printf "%s" "$password$salt" | sha256sum'$'\n'
  254. printf "%s\n" "$password_config" >> 'wiki/config'
  255. echo 'This was written to your config file:'
  256. echo '{{{'
  257. echo "$password_config"
  258. echo '}}}'
  259. echo
  260. echo "==$colorHeading Essential set of modules $colorNone=="
  261. echo 'Now we will install a couple of modules.'
  262. echo
  263. echo 'Oddmuse is very modular in nature, some of the very'
  264. echo 'essential stuff was separated from the core.'
  265. echo
  266. echo 'Although you can still use Oddmuse without any modules, we'
  267. echo 'think that any healthy wiki will require some of them.'
  268. echo
  269. echo 'This is discussed in https://oddmuse.org/wiki/Essential_Set_of_Modules'
  270. echo
  271. echo 'Next steps will guide you through installing some of the modules.'
  272. echo
  273. echo "===$colorHeading creole.pl $colorNone==="
  274. echo 'First of all, you need something that will handle the syntax on your wiki.'
  275. echo
  276. echo 'These modules will give you bold, italics, tables, sometimes additional link'
  277. echo 'patterns, ordered/unordered lists and lots of other stuff.'
  278. echo
  279. echo 'There are several modules for this, but [[Creole Markup Extension]] is'
  280. echo 'currently the best choice.'
  281. echo
  282. prompt 'Do you want to install [[Creole Markup Extension]]?' Y
  283. wget -nv -O wiki/modules/creole.pl "$REPO_LINK/modules/creole.pl" || err 'Cannot download the module (creole.pl).'
  284. echo
  285. echo '* [[Creole Markup Extension]] was installed into ##wiki/modules/creole.pl##.'
  286. echo
  287. echo "===$colorHeading questionasker.pl $colorNone==="
  288. echo 'Any website that has an edit form is bound to accumulate spam over time.'
  289. echo
  290. echo 'Unfortunately, that’s the Internet we are living in - spam bots crawl'
  291. echo 'the web and attempt to put stuff into anything that they can find.'
  292. echo
  293. echo 'Once you get at least one successful spam edit, you will be added to'
  294. echo 'the list and bots will attempt to post spam all the time.'
  295. echo
  296. echo 'There is no solution that will keep your wiki 100% free from spam,'
  297. echo 'but there are some good ways to mitigate it.'
  298. echo
  299. echo '[[QuestionAsker Extension]] will add a question to the edit form.'
  300. echo 'Once it is answered, the user gets a cookie and will not be asked the question again.'
  301. echo 'Surprisingly, this keeps almost all of the spambots away.'
  302. echo
  303. prompt 'Do you want to install [[QuestionAsker Extension]]?' Y
  304. wget -nv -O wiki/modules/questionasker.pl "$REPO_LINK/modules/questionasker.pl" || err 'Cannot download the module (questionasker.pl).'
  305. echo
  306. echo '* [[QuestionAsker Extension]] was installed into ##wiki/modules/questionasker.pl##.'
  307. echo
  308. echo "===$colorHeading ban-contributors.pl $colorNone==="
  309. echo 'Several times per year some spam will get through.'
  310. echo 'You will rollback your pages, but after some time it will appear again.'
  311. echo
  312. echo 'That’s when you might want to ban some IPs.'
  313. echo
  314. echo '[[Ban Contributors Extension]] will help you with that!'
  315. echo 'Whenever you rollback a page, it will provide several ways to prevent'
  316. echo 'that spam from getting in again.'
  317. echo
  318. echo 'Basically, it will add a convenient way to ban some IPs.'
  319. echo
  320. prompt 'Do you want to install [[Ban Contributors Extension]]?' Y
  321. wget -nv -O wiki/modules/ban-contributors.pl "$REPO_LINK/modules/ban-contributors.pl" || err 'Cannot download the module (ban-contributors.pl).'
  322. echo
  323. echo '* [[Ban Contributors Extension]] was installed into ##wiki/modules/ban-contributors.pl##.'
  324. echo
  325. if [[ ! -f 'wiki/css/wiki.css' ]]; then
  326. echo "==$colorHeading CSS $colorNone=="
  327. echo 'By default, the main script will attempt to use default stylsheet.'
  328. echo
  329. echo 'https://oddmuse.org is also using the default stylesheet.'
  330. echo 'Feel free to visit it to get the impression.'
  331. echo
  332. echo 'However, you probably want your users to download it from your own server.'
  333. echo
  334. echo 'If you want to add your own modifications - just edit that css file directly.'
  335. echo
  336. prompt 'Do you want to fetch default CSS into ##css/wiki.css##?' Y # TODO
  337. echo
  338. mkdir -p 'css'
  339. wget -nv -O css/wiki.css "$REPO_LINK/css/wiki.css" || err 'Cannot download default stylesheet.'
  340. stylesheet_config="\$StyleSheet = 'css/wiki.css'"
  341. printf "%s\n" "$stylesheet_config" >> 'wiki/config'
  342. echo 'This was written to your config file:'
  343. echo '{{{'
  344. echo "$stylesheet_config"
  345. echo '}}}'
  346. fi
  347. echo
  348. echo
  349. echo "==$colorHeading Finish $colorNone=="
  350. echo 'Congratulations! You went through all of the steps.'
  351. echo 'Now open your website and enjoy the result.'
  352. echo
  353. echo 'If you have problems or questions, please write a comment on https://oddmuse.org/.'
  354. echo 'We will be glad to help you!'
  355. echo
  356. echo 'Tell others about your wiki!'
  357. echo 'You can add your website to the list on https://oddmuse.org/wiki/Users'
  358. echo
  359. exit_reason='ok'