#!/bin/bash # Copyright (C) 2015 Alex-Daniel Jakimenko # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation, either version 3 of the License, or (at your option) any later # version. # # 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, see . set -e # fatal errors REPO_LINK='https://raw.githubusercontent.com/kensanata/oddmuse/2.3.5/' exit_reason='' # We will use alternating colors so that it is easier to see which part # was just printed. Otherwise it is pretty hard to use. color1=$(tput setaf 4) color2=$(tput setaf 6) colorHeading=$(tput setaf 2) colorNone=$(tput sgr0) prompt() { local answer prompt default if [[ ! $2 || ${2^} = Y* ]]; then prompt='Y/n' default='Y' elif [[ ${2^} = N* ]]; then prompt='y/N' default='N' fi while :; do if [[ $curColor == "$color2" ]]; then # TODO more colors? curColor=$color1 else curColor=$color2 fi read -r -p "$curColor$1$colorNone [$prompt] " answer [[ ! $answer ]] && answer=$default if [[ ${answer^} = Y* ]]; then echo return 0 fi if [[ ${answer^} = N* ]]; then echo return 1 fi done } err() { printf "%s\n" "$1" exit_reason='err' exit } clean() { case $exit_reason in ok) echo 'Good luck! (:' exit 0; ;; quit) echo 'You have aborted this script.' exit 1 ;; *) echo 'This script terminated unexpectedly. :(' exit 1 esac } trap clean EXIT echo "==$colorHeading Welcome! $colorNone==" echo 'This script will guide you through the process of **setting up a new** Oddmuse wiki.' echo 'It will also attempt to explain every step.' echo echo 'Every step will ask your confirmation. It will look like "[Y/n]".' echo 'Enter "y" (yes) or "n" (no) to answer the question.' echo 'Uppercase letter means that this action is the default and you can just press Enter.' echo echo 'At any moment you can press Ctrl-C to abort the process.' echo echo "==$colorHeading Main script $colorNone==" echo 'First of all, we have to download the main script and put it into ##cgi-bin## directory.' if [[ ! -d 'cgi-bin' ]]; then echo echo 'It seems like your ##cgi-bin## directory is missing.' echo if ! prompt 'Do you want to create cgi-bin now?' Y; then echo 'You decided not to create ##cgi-bin## folder.' echo 'This script was meant for simple setups with cgi-bin folder.' echo 'See https://oddmuse.org/wiki/Setup for manual installation instructions.' exit_reason='quit' exit fi mkdir -- 'cgi-bin' || err 'Cannot create cgi-bin directory. This may be caused by the lack of permissions.' echo '* ##cgi-bin## directory was created.' chmod 755 -- 'cgi-bin' echo '* ##cgi-bin## permissions were set to 755 (rwxr-xr-x).' cat <<'EOF' > 'cgi-bin/.htaccess' Options +ExecCGI SetHandler cgi-script EOF echo '* ##cgi-bin/.htaccess## file was created with these contents:' echo '{{{' cat 'cgi-bin/.htaccess' echo '}}}' fi echo if ! prompt 'Download wiki.pl right now?' Y; then echo 'You have decided not to download the script, but you cannot use Oddmuse without downloading it first.' echo echo 'See https://oddmuse.org/wiki/Setup for manual installation instructions.' exit fi wget -nv -O cgi-bin/wiki.pl "$REPO_LINK/wiki.pl" || err 'Cannot download the main script (wiki.pl).' echo echo '* ##wiki.pl## was successfully downloaded into your ##cgi-bin## directory.' chmod +x 'cgi-bin/wiki.pl' echo '* ##cgi-bin/wiki.pl## file is now executable.' echo echo "==$colorHeading Data directory $colorNone==" echo 'You have to specify some location for permanent data storage.' echo echo 'If you wont do that, the wiki will run in **temporary mode**.' echo echo 'In temporary mode, any change is stored in /tmp (and therefore will be eventually deleted).' echo echo 'In order to keep the data you must specify ##$DataDir##.' echo echo 'The easiest way to do that is to set ##WikiDataDir## environment variable in ##.htaccess##.' echo echo 'This will be appended to your ##.htaccess## file:' echo '{{{' echo 'SetEnv WikiDataDir ../wiki' echo '}}}' echo if ! prompt 'Set WikiDataDir environment variable?' Y; then echo 'You have decided not to use WikiDataDir environment variable.' echo echo 'This means that you have to use a wrapper script instead.' echo echo 'See https://oddmuse.org/wiki/Setup for more instructions.' exit fi echo >> '.htaccess' echo 'SetEnv WikiDataDir ../wiki' >> '.htaccess' echo '* WikiDataDir variable is now conigured to ##../wiki## (relative to ##cgi-bin## directory).' echo echo "==$colorHeading Basic setup $colorNone==" echo if [[ ! -d 'wiki/' ]]; then echo "===$colorHeading wiki/ $colorNone===" echo '##wiki/## directory will contain all data associated with your wiki, that is:' echo '* Pages and kept pages (previous versions)' echo '* Modules (also called Extensions)' echo '* Temp files and logs' echo '* And some other less relevant stuff' echo prompt 'Create ##wiki/## directory?' Y mkdir 'wiki' echo '##wiki/## directory was created.' echo fi if [[ ! -d 'wiki/modules/' ]]; then echo "===$colorHeading wiki/modules/ $colorNone===" echo '##wiki/modules/## can contain perl files that extend the functionality of the core.' echo 'These could be your own modules, or one of the 200+ contributed modules.' echo 'You can see a structured list of modules on https://oddmuse.org/wiki/Site_Map' echo prompt 'Create ##wiki/modules## directory?' Y mkdir 'wiki/modules' echo '##wiki/modules/## directory was created.' echo fi if [[ ! -f 'wiki/config' ]]; then echo "===$colorHeading wiki/config $colorNone===" default_config=$'use utf8; # allow utf-8 characters in config file\n' echo '##wiki/config## can contain perl code that will be ran during the core initialization on each request.' echo echo 'Config file will be initialized in ##wiki/config## with these contents:' echo '{{{' echo "$default_config" echo '}}}' echo prompt 'Initialize config file?' Y printf "%s\n" "$default_config" >> 'wiki/config' echo 'Config file was initialized.' echo fi if [[ ! -f '.htaccess' ]]; then main_htaccess='# Do not let people see your directory structure Options -Indexes # Make your wiki accessible with just /SomePage instead of /cgi-bin/run.pl/SomePage RewriteEngine On RewriteRule ^([^/]*)$ /cgi-bin/run.pl/$1 [QSA,L] RewriteRule ^$ cgi-bin/run.pl [QSA,L,PT]' echo "===$colorHeading .htaccess $colorNone===" echo '##.htaccess## is a configuration file that is used by several web servers (e.g. Apache).' echo '##.htaccess## file will be created with these contents:' echo '{{{' echo "$main_htaccess" echo '}}}' echo prompt 'Create ##.htaccess## file?' Y printf "%s\n" "$main_htaccess" >> '.htaccess' echo '##.htaccess## was created.' echo fi if [[ ! -f 'wiki/.htaccess' ]]; then wiki_htaccess='# Hide this directory from world Deny from all' echo "===$colorHeading wiki/.htaccess $colorNone===" echo 'We have to hide files in ##wiki/## from public.' echo '##wiki/.htaccess## file be created with these contents:' echo '{{{' echo "$wiki_htaccess" echo '}}}' echo prompt 'Create ##wiki/.htaccess## file?' Y printf "%s\n" "$wiki_htaccess" >> 'wiki/.htaccess' echo '##wiki/.htaccess## was created.' echo fi echo "==$colorHeading Config file $colorNone==" echo 'Now we will do a couple of modifications to the ##wiki/config## file.' echo echo 'Config file is just a perl script that is ran by the core during initialization.' echo echo 'Feel free to edit it yourself manually at any time!' echo echo "===$colorHeading Password $colorNone===" echo 'It is a good idea to have administrator password set.' echo echo 'This script will hash your salted password with sha256 and then it' echo 'will save that hash in your config file.' echo echo 'Although salt is used, it is still easy to bruteforce sha256 hashes.' echo 'If you think that bcrypt is a better option, you can change your config file later.' echo echo 'Please use a strong password (we will let you decide yourself which' echo 'password is strong enough, you can use any characters).' echo prompt 'Do you want to set your password now?' Y echo '//You will not see what you are typing, this is OK.//' read -rs -p "Password:" password echo echo password_config='use Digest::SHA qw(sha256_hex); $PassHashFunction = \&sha256_hex; ' salt=$(head -c 32 /dev/urandom | xxd -p -c 32) # urandom is OK for generating random strings password_config+="\$PassSalt = '$salt'; # random salt. Generated with: head -c 32 /dev/urandom | xxd -p -c 32"$'\n' password_config+="\$AdminPass = '$(printf "%s" "$password$salt" | sha256sum | cut -d ' ' -f 1)'"'; # Generated with: printf "%s" "$password$salt" | sha256sum'$'\n' printf "%s\n" "$password_config" >> 'wiki/config' echo 'This was written to your config file:' echo '{{{' echo "$password_config" echo '}}}' echo echo "==$colorHeading Essential set of modules $colorNone==" echo 'Now we will install a couple of modules.' echo echo 'Oddmuse is very modular in nature, some of the very' echo 'essential stuff was separated from the core.' echo echo 'Although you can still use Oddmuse without any modules, we' echo 'think that any healthy wiki will require some of them.' echo echo 'This is discussed in https://oddmuse.org/wiki/Essential_Set_of_Modules' echo echo 'Next steps will guide you through installing some of the modules.' echo echo "===$colorHeading creole.pl $colorNone===" echo 'First of all, you need something that will handle the syntax on your wiki.' echo echo 'These modules will give you bold, italics, tables, sometimes additional link' echo 'patterns, ordered/unordered lists and lots of other stuff.' echo echo 'There are several modules for this, but [[Creole Markup Extension]] is' echo 'currently the best choice.' echo prompt 'Do you want to install [[Creole Markup Extension]]?' Y wget -nv -O wiki/modules/creole.pl "$REPO_LINK/modules/creole.pl" || err 'Cannot download the module (creole.pl).' echo echo '* [[Creole Markup Extension]] was installed into ##wiki/modules/creole.pl##.' echo echo "===$colorHeading questionasker.pl $colorNone===" echo 'Any website that has an edit form is bound to accumulate spam over time.' echo echo 'Unfortunately, that’s the Internet we are living in - spam bots crawl' echo 'the web and attempt to put stuff into anything that they can find.' echo echo 'Once you get at least one successful spam edit, you will be added to' echo 'the list and bots will attempt to post spam all the time.' echo echo 'There is no solution that will keep your wiki 100% free from spam,' echo 'but there are some good ways to mitigate it.' echo echo '[[QuestionAsker Extension]] will add a question to the edit form.' echo 'Once it is answered, the user gets a cookie and will not be asked the question again.' echo 'Surprisingly, this keeps almost all of the spambots away.' echo prompt 'Do you want to install [[QuestionAsker Extension]]?' Y wget -nv -O wiki/modules/questionasker.pl "$REPO_LINK/modules/questionasker.pl" || err 'Cannot download the module (questionasker.pl).' echo echo '* [[QuestionAsker Extension]] was installed into ##wiki/modules/questionasker.pl##.' echo echo "===$colorHeading ban-contributors.pl $colorNone===" echo 'Several times per year some spam will get through.' echo 'You will rollback your pages, but after some time it will appear again.' echo echo 'That’s when you might want to ban some IPs.' echo echo '[[Ban Contributors Extension]] will help you with that!' echo 'Whenever you rollback a page, it will provide several ways to prevent' echo 'that spam from getting in again.' echo echo 'Basically, it will add a convenient way to ban some IPs.' echo prompt 'Do you want to install [[Ban Contributors Extension]]?' Y wget -nv -O wiki/modules/ban-contributors.pl "$REPO_LINK/modules/ban-contributors.pl" || err 'Cannot download the module (ban-contributors.pl).' echo echo '* [[Ban Contributors Extension]] was installed into ##wiki/modules/ban-contributors.pl##.' echo if [[ ! -f 'wiki/css/wiki.css' ]]; then echo "==$colorHeading CSS $colorNone==" echo 'By default, the main script will attempt to use default stylsheet.' echo echo 'https://oddmuse.org is also using the default stylesheet.' echo 'Feel free to visit it to get the impression.' echo echo 'However, you probably want your users to download it from your own server.' echo echo 'If you want to add your own modifications - just edit that css file directly.' echo prompt 'Do you want to fetch default CSS into ##css/wiki.css##?' Y # TODO echo mkdir -p 'css' wget -nv -O css/wiki.css "$REPO_LINK/css/wiki.css" || err 'Cannot download default stylesheet.' stylesheet_config="\$StyleSheet = 'css/wiki.css'" printf "%s\n" "$stylesheet_config" >> 'wiki/config' echo 'This was written to your config file:' echo '{{{' echo "$stylesheet_config" echo '}}}' fi echo echo echo "==$colorHeading Finish $colorNone==" echo 'Congratulations! You went through all of the steps.' echo 'Now open your website and enjoy the result.' echo echo 'If you have problems or questions, please write a comment on https://oddmuse.org/.' echo 'We will be glad to help you!' echo echo 'Tell others about your wiki!' echo 'You can add your website to the list on https://oddmuse.org/wiki/Users' echo exit_reason='ok'