#!/usr/bin/perl # Setup file for ikiwiki. # # Passing this to ikiwiki --setup will make ikiwiki generate # wrappers and build the wiki. # # Remember to re-run ikiwiki --setup any time you edit this file. use IkiWiki::Setup::Standard { # name of the wiki wikiname => 'MyWiki', # contact email for wiki #adminemail => 'me@example.org', # users who are wiki admins adminuser => [], # users who are banned from the wiki banned_users => [], # where the source of the wiki is located srcdir => $ENV{'HOME'} . '/private_webdata/samplewiki/content', # where to build the wiki destdir => $ENV{'HOME'} . '/public_websites/admin.wiki.example.org', # base url to the wiki url => 'http://admin.wiki.example.org', # url to the ikiwiki.cgi cgiurl => 'http://admin.wiki.example.org/ikiwiki.cgi', # cgi wrapper to generate cgi_wrapper => $ENV{'HOME'} . '/public_cgi/admin.wiki.example.org/ikiwiki.cgi', # mode for cgi_wrapper (can safely be made suid) cgi_wrappermode => '06755', # rcs backend to use rcs => '', # plugins to add to the default configuration add_plugins => [], # plugins to disable disable_plugins => [], # location of template files templatedir => $ENV{'HOME'} . '/private_webdata/samplewiki/templates', # base wiki source location underlaydir => $ENV{'HOME'} . '/private_webdata/samplewiki/basewiki', # display verbose messages when building? #verbose => 1, # log to syslog? #syslog => 1, # create output files named page/index.html? usedirs => 1, # use '!'-prefixed preprocessor directives? prefix_directives => 1, # use page/index.mdwn source files indexpages => 0, # enable Discussion pages? discussion => 1, # only send cookies over SSL connections? sslcookie => 0, # extension to use for new pages default_pageext => 'mdwn', # extension to use for html files htmlext => 'html', # strftime format string to display date timeformat => '%c', # UTF-8 locale to use #locale => 'en_US.UTF-8', # put user pages below specified page userdir => '', # how many backlinks to show before hiding excess (0 to show all) numbacklinks => 10, # attempt to hardlink source files? (optimisation for large files) hardlink => 0, # force ikiwiki to use a particular umask #umask => 022, # extra library and plugin directory libdir => $ENV{'HOME'} . '/private_webdata/samplewiki/perl', # environment variables ENV => {}, # regexp of source files to ignore #exclude => '\\.wav$', # specifies the characters that are allowed in source filenames wiki_file_chars => '-[:alnum:]+/.:_', # allow symlinks in the path leading to the srcdir (potentially insecure) allow_symlinks_before_srcdir => 0, # aggregate plugin # enable aggregation to internal pages? #aggregateinternal => 0, # allow aggregation to be triggered via the web? #aggregate_webtrigger => 0, # amazon_s3 plugin # public access key id #amazon_s3_key_id => 'XXXXXXXXXXXXXXXXXXXX', # file holding secret key (must not be readable by others!) #amazon_s3_key_id => $ENV{'HOME'} . '/secret_webdata/s3_key', # globally unique name of bucket to store wiki in #amazon_s3_bucket => 'mywiki', # a prefix to prepend to each page name #amazon_s3_prefix => 'wiki/', # which S3 datacenter to use (leave blank for default) #amazon_s3_location => 'EU', # store each index file twice? (allows urls ending in "/index.html" and "/") #amazon_s3_dupindex => 0, # anonok plugin # PageSpec to limit which pages anonymous users can edit #anonok_pagespec => '*/discussion', # attachment plugin # enhanced PageSpec specifying what attachments are allowed #allowed_attachments => 'virusfree() and mimetype(image/*) and maxsize(50kb)', # virus checker program (reads STDIN, returns nonzero if virus found) #virus_checker => 'clamdscan -', # bzr plugin # bzr post-commit hook to generate #bzr_wrapper => '', # mode for bzr_wrapper (can safely be made suid) #bzr_wrappermode => '06755', # url to show file history, using loggerhead ([[file]] substituted) #historyurl => '', # url to view a diff, using loggerhead ([[file]] and [[r2]] substituted) #diffurl => 'http://example.org/revision?start_revid=[[r2]]#[[file]]-s', # calendar plugin # base of the archives hierarchy #archivebase => 'archives', # git plugin # git hook to generate #git_wrapper => $ENV{'HOME'} . '/public_websites/git.example.org/samplewiki_content.git/hooks/post-update-ikiwiki-admin', # mode for git_wrapper (can safely be made suid) #git_wrappermode => '06755', # gitweb url to show file history ([[file]] substituted) #historyurl => 'http://git.example.org/gitweb.cgi?p=wiki.git;a=history;f=[[file]]', # ;hb=master # gitweb url to show a diff ([[sha1_to]], [[sha1_from]], [[sha1_parent]], and [[file]] substituted) #diffurl => 'http://git.example.org/gitweb.cgi?p=wiki.git;a=blobdiff;h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_parent]];f=[[file]]', # where to pull and push changes (set to empty string to disable) #gitorigin_branch => 'samplewiki', # branch that the wiki is stored in #gitmaster_branch => 'master', # htmlscrubber plugin # PageSpec specifying pages not to scrub #htmlscrubber_skip => '!*/Discussion', # inline plugin # enable rss feeds by default? #rss => 0, # enable atom feeds by default? #atom => 0, # allow rss feeds to be used? #allowrss => 0, # allow atom feeds to be used? #allowatom => 0, # urls to ping (using XML-RPC) on feed update #pingurl => 'http://rpc.technorati.com/rpc/ping', # listdirectives plugin # directory in srcdir that contains directive descriptions #directive_description_dir => 'ikiwiki/directive', # lockedit plugin # PageSpec controlling which pages are locked #locked_pages => '!*/Discussion', # mdwn plugin # enable multimarkdown features? #multimarkdown => 0, # mercurial plugin # mercurial post-commit hook to generate #mercurial_wrapper => '', # mode for mercurial_wrapper (can safely be made suid) #mercurial_wrappermode => '06755', # url to hg serve'd repository, to show file history ([[file]] substituted) #historyurl => 'http://example.org:8000/log/tip/[[file]]', # url to hg serve'd repository, to show diff ([[file]] and [[r2]] substituted) #diffurl => 'http://localhost:8000/?fd=[[r2]];file=[[file]]', # mirrorlist plugin # list of mirrors #mirrorlist => {}, # openid plugin # an url where users can signup for an OpenID #openidsignup => 'http://myopenid.com/', # passwordauth plugin # a password that must be entered when signing up for an account #account_creation_password => 's3cr1t', # cost of generating a password using Authen::Passphrase::BlowfishCrypt #password_cost => 8, # pinger plugin # how many seconds to try pinging before timing out #pinger_timeout => 15, # prettydate plugin # format to use to display date #prettydateformat => '%X, %B %o, %Y', # recentchanges plugin # name of the recentchanges page #recentchangespage => 'recentchanges', # number of changes to track #recentchangesnum => 100, # search plugin # path to the omega cgi program #omega_cgi => '/usr/lib/cgi-bin/omega/omega', # svn plugin # subversion repository location #svnrepo => '/svn/wiki', # path inside repository where the wiki is located #svnpath => 'trunk', # svn post-commit hook to generate #svn_wrapper => '/svn/wikirepo/hooks/post-commit', # mode for svn_wrapper (can safely be made suid) #svn_wrappermode => '04755', # viewvc url to show file history ([[file]] substituted) #historyurl => 'http://svn.example.org/trunk/[[file]]', # viewvc url to show a diff ([[file]], [[r1]], and [[r2]] substituted) #diffurl => 'http://svn.example.org/trunk/[[file]]?root=wiki&r1=[[r1]]&r2=[[r2]]', # tag plugin # parent page tags are located under #tagbase => 'tag', # teximg plugin # Should teximg use dvipng to render, or dvips and convert? #teximg_dvipng => '', # LaTeX prefix for teximg plugin #teximg_prefix => '\\documentclass{article} #\\usepackage{amsmath} #\\usepackage{amsfonts} #\\usepackage{amssymb} #\\pagestyle{empty} #\\begin{document} #', # LaTeX postfix for teximg plugin #teximg_postfix => '\\end{document}', # tla plugin # tla post-commit hook to generate #tla_wrapper => '', # mode for tla_wrapper (can safely be made suid) #tla_wrappermode => '06755', # url to show file history ([[file]] substituted) #historyurl => '', # url to show a diff ([[file]] and [[rev]] substituted) #diffurl => '', # typography plugin # Text::Typography attributes value #typographyattributes => '3', # websetup plugin # list of plugins that cannot be enabled/disabled via the web interface #websetup_force_plugins => [], # show unsafe settings, read-only, in web interface? #websetup_show_unsafe => 1, # varioki plugin (strings are eval'ed: double-quote actual strings!) #varioki => { # 'branding_logo_text' => '"Example Website"', # 'branding_logo' => '"logo.png"', # 'branding_logo_tagline' => '"Yet another ikiwiki site!"', #}, } pan>,
  • },
  • }
  • # Checks if a string matches a user's password, and returns true or false.
  • sub checkpassword ($$;$) {
  • my $user=shift;
  • my $password=shift;
  • my $field=shift || "password";
  • # It's very important that the user not be allowed to log in with
  • # an empty password!
  • if (! length $password) {
  • return 0;
  • }
  • my $userinfo=IkiWiki::userinfo_retrieve();
  • if (! length $user || ! defined $userinfo ||
  • ! exists $userinfo->{$user} || ! ref $userinfo->{$user}) {
  • return 0;
  • }
  • my $ret=0;
  • if (exists $userinfo->{$user}->{"crypt".$field}) {
  • eval q{use Authen::Passphrase};
  • error $@ if $@;
  • my $p = Authen::Passphrase->from_crypt($userinfo->{$user}->{"crypt".$field});
  • $ret=$p->match($password);
  • }
  • elsif (exists $userinfo->{$user}->{$field}) {
  • $ret=$password eq $userinfo->{$user}->{$field};
  • }
  • if ($ret &&
  • (exists $userinfo->{$user}->{resettoken} ||
  • exists $userinfo->{$user}->{cryptresettoken})) {
  • # Clear reset token since the user has successfully logged in.
  • delete $userinfo->{$user}->{resettoken};
  • delete $userinfo->{$user}->{cryptresettoken};
  • IkiWiki::userinfo_store($userinfo);
  • }
  • return $ret;
  • }
  • sub setpassword ($$;$) {
  • my $user=shift;
  • my $password=shift;
  • my $field=shift || "password";
  • eval q{use Authen::Passphrase::BlowfishCrypt};
  • if (! $@) {
  • my $p = Authen::Passphrase::BlowfishCrypt->new(
  • cost => $config{password_cost} || 8,
  • salt_random => 1,
  • passphrase => $password,
  • );
  • IkiWiki::userinfo_set($user, "crypt$field", $p->as_crypt);
  • IkiWiki::userinfo_set($user, $field, "");
  • }
  • else {
  • IkiWiki::userinfo_set($user, $field, $password);
  • }
  • }
  • sub formbuilder_setup (@) {
  • my %params=@_;
  • my $form=$params{form};
  • my $session=$params{session};
  • my $cgi=$params{cgi};
  • if ($form->title eq "signin" || $form->title eq "register" || $cgi->param("do") eq "register") {
  • $form->field(name => "name", required => 0);
  • $form->field(name => "password", type => "password", required => 0);
  • if ($form->submitted eq "Register" || $form->submitted eq "Create Account" || $cgi->param("do") eq "register") {
  • $form->field(name => "confirm_password", type => "password");
  • $form->field(name => "account_creation_password", type => "password")
  • if (defined $config{account_creation_password} &&
  • length $config{account_creation_password});
  • $form->field(name => "email", size => 50);
  • $form->title("register");
  • $form->text("");
  • $form->field(name => "confirm_password",
  • validate => sub {
  • shift eq $form->field("password");
  • },
  • );
  • $form->field(name => "password",
  • validate => sub {
  • shift eq $form->field("confirm_password");
  • },
  • );
  • }
  • if ($form->submitted) {
  • my $submittype=$form->submitted;
  • # Set required fields based on how form was submitted.
  • my %required=(
  • "Login" => [qw(name password)],
  • "Register" => [],
  • "Create Account" => [qw(name password confirm_password email)],
  • "Reset Password" => [qw(name)],
  • );
  • foreach my $opt (@{$required{$submittype}}) {
  • $form->field(name => $opt, required => 1);
  • }
  • if ($submittype eq "Create Account") {
  • $form->field(
  • name => "account_creation_password",
  • validate => sub {
  • shift eq $config{account_creation_password};
  • },
  • required => 1,
  • ) if (defined $config{account_creation_password} &&
  • length $config{account_creation_password});
  • $form->field(
  • name => "email",
  • validate => "EMAIL",
  • );
  • }
  • # Validate password against name for Login.
  • if ($submittype eq "Login") {
  • $form->field(
  • name => "password",
  • validate => sub {
  • checkpassword($form->field("name"), shift);
  • },
  • );
  • }
  • elsif ($submittype eq "Register" ||
  • $submittype eq "Create Account" ||
  • $submittype eq "Reset Password") {
  • $form->field(name => "password", validate => 'VALUE');
  • }
  • # And make sure the entered name exists when logging
  • # in or sending email, and does not when registering.
  • if ($submittype eq 'Create Account' ||
  • $submittype eq 'Register') {
  • $form->field(
  • name => "name",
  • validate => sub {
  • my $name=shift;
  • length $name &&
  • $name=~/$config{wiki_file_regexp}/ &&
  • ! IkiWiki::userinfo_get($name, "regdate");
  • },
  • );
  • }
  • elsif ($submittype eq "Login" ||
  • $submittype eq "Reset Password") {
  • $form->field(
  • name => "name",
  • validate => sub {
  • my $name=shift;
  • length $name &&
  • IkiWiki::userinfo_get($name, "regdate");
  • },
  • );
  • }
  • }
  • else {
  • # First time settings.
  • $form->field(name => "name");
  • if ($session->param("name")) {
  • $form->field(name => "name", value => $session->param("name"));
  • }
  • }
  • }
  • elsif ($form->title eq "preferences") {
  • my $user=$session->param("name");
  • if (! IkiWiki::openiduser($user)) {
  • $form->field(name => "name", disabled => 1,
  • value => $user, force => 1,
  • fieldset => "login");
  • $form->field(name => "password", type => "password",
  • fieldset => "login",
  • validate => sub {
  • shift eq $form->field("confirm_password");
  • });
  • $form->field(name => "confirm_password", type => "password",
  • fieldset => "login",
  • validate => sub {
  • shift eq $form->field("password");
  • });
  • my $userpage=IkiWiki::userpage($user);
  • if (exists $pagesources{$userpage}) {
  • $form->text(gettext("Your user page: ").
  • htmllink("", "", $userpage,
  • noimageinline => 1));
  • }
  • else {
  • $form->text("<a href=\"".
  • IkiWiki::cgiurl(do => "edit", page => $userpage).
  • "\">".gettext("Create your user page")."</a>");
  • }
  • }
  • }
  • }
  • sub formbuilder (@) {
  • my %params=@_;
  • my $form=$params{form};
  • my $session=$params{session};
  • my $cgi=$params{cgi};
  • my $buttons=$params{buttons};
  • if ($form->title eq "signin" || $form->title eq "register") {
  • if (($form->submitted && $form->validate) || $cgi->param("do") eq "register") {
  • if ($form->submitted eq 'Login') {
  • $session->param("name", $form->field("name"));
  • IkiWiki::cgi_postsignin($cgi, $session);
  • }
  • elsif ($form->submitted eq 'Create Account') {
  • my $user_name=$form->field('name');
  • if (IkiWiki::userinfo_setall($user_name, {
  • 'email' => $form->field('email'),
  • 'regdate' => time})) {
  • setpassword($user_name, $form->field('password'));
  • $form->field(name => "confirm_password", type => "hidden");
  • $form->field(name => "email", type => "hidden");
  • $form->text(gettext("Account creation successful. Now you can Login."));
  • }
  • else {
  • error(gettext("Error creating account."));
  • }
  • }
  • elsif ($form->submitted eq 'Reset Password') {
  • my $user_name=$form->field("name");
  • my $email=IkiWiki::userinfo_get($user_name, "email");
  • if (! length $email) {
  • error(gettext("No email address, so cannot email password reset instructions."));
  • }
  • # Store a token that can be used once
  • # to log the user in. This needs to be hard
  • # to guess. Generating a cgi session id will
  • # make it as hard to guess as any cgi session.
  • eval q{use CGI::Session};
  • error($@) if $@;
  • my $token = CGI::Session->new->id;
  • setpassword($user_name, $token, "resettoken");
  • my $template=template("passwordmail.tmpl");
  • $template->param(
  • user_name => $user_name,
  • passwordurl => IkiWiki::cgiurl(
  • 'do' => "reset",
  • 'name' => $user_name,
  • 'token' => $token,
  • ),
  • wikiurl => $config{url},
  • wikiname => $config{wikiname},
  • REMOTE_ADDR => $ENV{REMOTE_ADDR},
  • );
  • eval q{use Mail::Sendmail};
  • error($@) if $@;
  • sendmail(
  • To => IkiWiki::userinfo_get($user_name, "email"),
  • From => "$config{wikiname} admin <".
  • (defined $config{adminemail} ? $config{adminemail} : "")
  • .">",
  • Subject => "$config{wikiname} information",
  • Message => $template->output,
  • ) or error(gettext("Failed to send mail"));
  • $form->text(gettext("You have been mailed password reset instructions."));
  • $form->field(name => "name", required => 0);