From 3549785897093452a5c523e517ac42842bea694d Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Tue, 19 Feb 2008 17:28:28 -0500
Subject: [PATCH] First steps to implement an installer

---
 installer/images/banner_right.gif |    0 
 installer/images/banner_bg.gif    |    0 
 installer/rcube_install.php       |  199 ++++++++++++++++
 installer/styles.css              |  186 +++++++++++++++
 installer/config.php              |  188 +++++++++++++++
 installer/check.php               |   10 
 installer/test.php                |   21 +
 installer/welcome.html            |   14 +
 installer/images/banner_logo.gif  |    0 
 installer/index.php               |   63 +++++
 10 files changed, 681 insertions(+), 0 deletions(-)

diff --git a/installer/check.php b/installer/check.php
new file mode 100644
index 0000000..49f1864
--- /dev/null
+++ b/installer/check.php
@@ -0,0 +1,10 @@
+<form action="index.php" method="get">
+<input type="hidden" name="_step" value="2" />
+<?php
+
+echo '<p>[do some tests as in check.php-dist here]</p>';
+
+echo '<input type="submit" value="NEXT" ' . ($RCI->failures ? 'disabled' : '') . ' />';
+
+?>
+</form>
diff --git a/installer/config.php b/installer/config.php
new file mode 100644
index 0000000..effbf2b
--- /dev/null
+++ b/installer/config.php
@@ -0,0 +1,188 @@
+<form action="index.php" method="post">
+<input type="hidden" name="_step" value="2" />
+<?php
+
+ini_set('display_errors', 1);
+require_once '../program/include/rcube_html.inc';
+
+?>
+<fieldset>
+<legend>General configuration</legend>
+<dl>
+<!--
+<dt class="propname">debug_level</dt>
+<dd>
+<?php
+/*
+$value = $RCI->getprop('debug_level');
+$check_debug = new checkbox(array('name' => '_debug_level[]'));
+echo $check_debug->show(($value & 1) ? 1 : 0 , array('value' => 1, 'id' => 'cfgdebug1'));
+echo '<label for="cfgdebug1">Log errors</label><br />';
+
+echo $check_debug->show(($value & 4) ? 4 : 0, array('value' => 4, 'id' => 'cfgdebug4'));
+echo '<label for="cfgdebug4">Display errors</label><br />';
+
+echo $check_debug->show(($value & 8) ? 8 : 0, array('value' => 8, 'id' => 'cfgdebug8'));
+echo '<label for="cfgdebug8">Verbose display</label><br />';
+*/
+?>
+</dd>
+-->
+
+<dt class="propname">product_name</dt>
+<dd>
+<?php
+
+$input_prodname = new textfield(array('name' => '_product_name', 'size' => 30, 'id' => "cfgprodname"));
+echo $input_prodname->show($RCI->getprop('product_name'));
+
+?>
+<div>The name of your service (used to compose page titles)</div>
+</dd>
+
+<dt class="propname">skin_path</dt>
+<dd>
+<?php
+
+$input_skinpath = new textfield(array('name' => '_skin_path', 'size' => 30, 'id' => "cfgskinpath"));
+echo $input_skinpath->show($RCI->getprop('skin_path'));
+
+?>
+<div>Relative path to the skin folder</div>
+</dd>
+
+<dt class="propname">temp_dir</dt>
+<dd>
+<?php
+
+$input_tempdir = new textfield(array('name' => '_temp_dir', 'size' => 30, 'id' => "cfgtempdir"));
+echo $input_tempdir->show($RCI->getprop('temp_dir'));
+
+?>
+<div>Use this folder to store temp files (must be writebale for webserver)</div>
+</dd>
+
+<dt class="propname">log_dir</dt>
+<dd>
+<?php
+
+$input_logdir = new textfield(array('name' => '_log_dir', 'size' => 30, 'id' => "cfglogdir"));
+echo $input_logdir->show($RCI->getprop('log_dir'));
+
+?>
+<div>Use this folder to store log files (must be writebale for webserver)</div>
+</dd>
+
+<dt class="propname">ip_check</dt>
+<dd>
+<?php
+
+$check_ipcheck = new checkbox(array('name' => '_ip_check', 'id' => "cfgipcheck"));
+echo $check_ipcheck->show(intval($RCI->getprop('ip_check')), array('value' => 1));
+
+?>
+<label for="cfgipcheck">Check client IP in session athorization</label><br />
+
+<p class="hint">This increases security but can cause sudden logouts when someone uses a proxy with changeing IPs.</p>
+</dd>
+
+<dt class="propname">des_key</dt>
+<dd>
+<?php
+
+$input_deskey = new textfield(array('name' => '_des_key', 'size' => 30, 'id' => "cfgdeskey"));
+echo $input_deskey->show($RCI->getprop('des_key'));
+
+?>
+<div>This key is used to encrypt the users imap password before storing in the session record</div>
+<p class="hint">It's a random generated string to ensure that every installation has it's own key.
+If you enter it manually please provide a string of exactly 24 chars.</p>
+</dd>
+
+<dt class="propname">enable_caching</dt>
+<dd>
+<?php
+
+$check_caching = new checkbox(array('name' => '_enable_caching', 'id' => "cfgcache"));
+echo $check_caching->show(intval($RCI->getprop('enable_caching')), array('value' => 1));
+
+?>
+<label for="cfgcache">Cache messages in local database</label><br />
+</dd>
+
+</dl>
+</fieldset>
+
+<fieldset>
+<legend>IMAP Settings</legend>
+<dl>
+<dt class="propname">auto_create_user</dt>
+<dd>
+<?php
+
+$check_autocreate = new checkbox(array('name' => '_auto_create_user', 'id' => "cfgautocreate"));
+echo $check_autocreate->show(intval($RCI->getprop('auto_create_user')), array('value' => 1));
+
+?>
+<label for="cfgautocreate">Automatically create a new RoundCube user when log-in the first time</label><br />
+
+<p class="hint">A user is authenticated by the IMAP server but it requires a local record to store settings
+and contacts. With this option enabled a new user record will automatically be created once the IMAP login succeeds.</p>
+
+<p class="hint">If this option is disabled, the login only succeeds if there's a matching user-record in the local RoundCube database
+what means that you have to create those records manually or disable this option after the first login.</p>
+</dd>
+
+</dl>
+</fieldset>
+
+<fieldset>
+<legend>SMTP Settings</legend>
+<dl>
+<dd>TBD.</dd>
+</dl>
+</fieldset>
+
+<fieldset>
+<legend>Display settings</legend>
+<dl>
+
+<dt class="propname">locale_string</dt>
+<dd>
+<?php
+
+$input_locale = new textfield(array('name' => '_locale_string', 'size' => 6, 'id' => "cfglocale"));
+echo $input_locale->show($RCI->getprop('locale_string'));
+
+?>
+<div>The default locale setting. This also defines the language of the login screen.</div>
+<p class="hint">Enter a <a href="http://www.faqs.org/rfcs/rfc1766">RFC1766</a> formatted locale name. Examples: en_US, de, de_CH, fr, pt_BR</p>
+</dd>
+
+</dl>
+</fieldset>
+
+<?php
+
+echo '<p><input type="submit" name="submit" value="UPDATE" ' . ($RCI->failures ? 'disabled' : '') . ' /></p>';
+
+
+if (!empty($_POST['submit'])) {
+  echo "<hr />\n";
+  
+  echo '<p class="notice">Copy the following configurations and save them in two files (names above the text box)';
+  echo ' within the <tt>config/</tt> directory of your RoundCube installation.</p>';
+  
+  $textbox = new textarea(array('rows' => 20, 'cols' => 60, 'class' => "configfile"));
+  
+  echo '<div><em>main.inc.php</em></div>';
+  echo $textbox->show($RCI->create_config('main'));
+  
+  echo '<div style="margin-top:1em"><em>db.inc.php</em></div>';
+  echo $textbox->show($RCI->create_config('db'));
+
+  echo '<p><input type="button" onclick="location.href=\'./index.php?_step=3\'" value="CONTINUE" /></p>';
+}
+
+?>
+</form>
diff --git a/installer/images/banner_bg.gif b/installer/images/banner_bg.gif
new file mode 100644
index 0000000..9cef8a7
--- /dev/null
+++ b/installer/images/banner_bg.gif
Binary files differ
diff --git a/installer/images/banner_logo.gif b/installer/images/banner_logo.gif
new file mode 100644
index 0000000..a7dd114
--- /dev/null
+++ b/installer/images/banner_logo.gif
Binary files differ
diff --git a/installer/images/banner_right.gif b/installer/images/banner_right.gif
new file mode 100644
index 0000000..3248668
--- /dev/null
+++ b/installer/images/banner_right.gif
Binary files differ
diff --git a/installer/index.php b/installer/index.php
new file mode 100644
index 0000000..be86577
--- /dev/null
+++ b/installer/index.php
@@ -0,0 +1,63 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<title>RoundCube Webmail Installer</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" type="text/css" href="styles.css" />
+</head>
+
+<body>
+
+<div id="banner">
+  <div id="header">
+    <div class="banner-logo"><a href="http://www.roundcube.net"><img src="images/banner_logo.gif" width="200" height="56" border="0" alt="RoundCube Webmal Project" /></a></div>
+    <div class="banner-right"><img src="images/banner_right.gif" width="10" height="56" alt="" /></div>
+  </div>
+  <div id="topnav">
+    <a href="http://trac.roundcube.net/wiki/Howto_Install">How-to Wiki</a>
+  </div>
+ </div>
+
+<div id="content">
+
+<h1>RoundCube Webmail Installer</h1>
+
+<?php
+
+  require_once 'rcube_install.php';
+  $RCI = new rcube_install();
+
+?>
+
+<ol id="progress">
+<?php
+  
+  foreach (array('Check environment', 'Create config', 'Test config') as $i => $item) {
+    $j = $i + 1;
+    $link = $RCI->step > $j ? '<a href="./index.php?_step='.$j.'">' . Q($item) . '</a>' : Q($item);
+    printf('<li class="step%d%s">%s</li>', $j+1, $RCI->step > $j ? ' passed' : ($RCI->step == $j ? ' current' : ''), $link);
+  }
+?>
+</ol>
+
+<?php
+
+$include_steps = array('welcome.html', 'check.php', 'config.php', 'test.php');
+
+if ($include_steps[$RCI->step]) {
+  include $include_steps[$RCI->step];
+}
+else {
+  header("HTTP/1.0 404 Not Found");
+  echo '<h2 class="error">Invalid step</h2>';
+}
+
+?>
+</div>
+
+<div id="footer">
+  Installer by the RoundCube Dev Team. Copyright &copy; 2008 - Published under the GNU Public License
+</div>
+</body>
+</html>
diff --git a/installer/rcube_install.php b/installer/rcube_install.php
new file mode 100644
index 0000000..eee0fb7
--- /dev/null
+++ b/installer/rcube_install.php
@@ -0,0 +1,199 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | rcube_install.php                                                     |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail package                    |
+ | Copyright (C) 2008, RoundCube Dev. - Switzerland                      |
+ | Licensed under the GNU Public License                                 |
+ +-----------------------------------------------------------------------+
+
+ $Id:  $
+
+*/
+
+
+/**
+ * Class to control the installation process of the RoundCube Webmail package
+ *
+ * @category Install
+ * @package  RoundCube
+ * @author Thomas Bruederli
+ */
+class rcube_install
+{
+  var $step;
+  var $failures = 0;
+  var $defaults = array();
+  
+  /**
+   * Constructor
+   */
+  function rcube_install()
+  {
+    $this->step = intval($_REQUEST['_step']);
+    $this->get_defaults();
+  }
+  
+  
+  /**
+   * Read the default config file and store properties
+   */
+  function get_defaults()
+  {
+    $suffix = is_readable('../config/main.inc.php.dist') ? '.dist' : '';
+    
+    include '../config/main.inc.php' . $suffix;
+    if (is_array($rcmail_config)) {
+      $this->defaults = $rcmail_config;
+    }
+      
+    include '../config/db.inc.php'. $suffix;
+    if (is_array($rcmail_config)) {
+      $this->defaults += $rcmail_config;
+    }
+  }
+  
+  
+  /**
+   * Getter for a certain config property
+   *
+   * @param string Property name
+   * @return string The property value
+   */
+  function getprop($name)
+  {
+    $value = isset($_REQUEST["_$name"]) ? $_REQUEST["_$name"] : $this->defaults[$name];
+    
+    if ($name == 'des_key' && !isset($_REQUEST["_$name"]))
+      $value = self::random_key(24);
+    
+    return $value;
+  }
+  
+  
+  /**
+   * Take the default config file and replace the parameters
+   * with the submitted form data
+   *
+   * @param string Which config file (either 'main' or 'db')
+   * @return string The complete config file content
+   */
+  function create_config($which)
+  {
+    $out = file_get_contents("../config/{$which}.inc.php.dist");
+    
+    if (!$out)
+      return '[Warning: could not read the template file]';
+    
+    foreach ($this->defaults as $prop => $default) {
+      $value = $_POST["_$prop"] ? $_POST["_$prop"] : $default;
+      
+      // skip this property
+      if (!isset($_POST["_$prop"]) || $value == $default)
+        continue;
+      
+      // convert some form data
+      if ($prop == 'debug_level' && is_array($value)) {
+        $val = 0;
+        foreach ($value as $i => $dbgval)
+          $val += intval($dbgval);
+        $value = $val;
+      }
+      else if (is_bool($default))
+        $value = is_numeric($value) ? (bool)$value : $value;
+      
+      // replace the matching line in config file
+      $out = preg_replace(
+        '/(\$rcmail_config\[\''.preg_quote($prop).'\'\])\s+=\s+(.+);/Uie',
+        "'\\1 = ' . var_export(\$value, true) . ';'",
+        $out);
+    }
+    
+    return $out;
+  }
+  
+  
+  /**
+   * Display OK status
+   *
+   * @param string Test name
+   * @param string Confirm message
+   */
+  function pass($name, $message = '')
+  {
+    echo Q($name) . ':&nbsp; <span class="success">OK</span>';
+    if ($message)
+      echo '<span class="indent">' . Q($name) . '</span>';
+  }
+  
+  
+  /**
+   * Display an error status and increase failure count
+   *
+   * @param string Test name
+   * @param string Error message
+   * @param string URL for details
+   */
+  function fail($name, $message = '', $url = '')
+  {
+    $this->failures++;
+    
+    echo Q($name) . ':&nbsp; <span class="fail">NOT OK</span>';
+    if ($message)
+      echo '<span class="indent">' . Q($name) . '</span>';
+    if ($url)
+      echo '<span class="indent">(See <a href="' . Q($url) . '" target="_blank">' . Q($url) . '</a>)</span>';
+  }
+  
+  
+  /**
+   * Display warning status
+   *
+   * @param string Test name
+   * @param string Warning message
+   * @param string URL for details
+   */
+  function warning($name, $message = '', $url = '')
+  {
+    echo Q($name) . ':&nbsp; <span class="warning">NOT AVAILABLE</span>';
+    if ($message)
+      echo '<span class="indent">' . Q($name) . '</span>';
+    if ($url)
+      echo '<span class="indent">(See <a href="' . Q($url) . '" target="_blank">' . Q($url) . '</a>)</span>';
+  }
+  
+  
+  /**
+   * Generarte a ramdom string to be used as encryption key
+   *
+   * @param int Key length
+   * @return string The generated random string
+   * @static
+   */
+  function random_key($length)
+  {
+    $alpha = 'ABCDEFGHIJKLMNOPQERSTUVXYZabcdefghijklmnopqrtsuvwxyz0123456789+*%&?!$-_=';
+    $out = '';
+    
+    for ($i=0; $i < $length; $i++)
+      $out .= $alpha{rand(0, strlen($alpha)-1)};
+    
+    return $out;
+  }
+  
+}
+
+
+/**
+ * Shortcut function for htmlentities()
+ *
+ * @param string String to quote
+ * @return string The html-encoded string
+ */
+function Q($string)
+{
+  return htmlentities($string);
+}
+
diff --git a/installer/styles.css b/installer/styles.css
new file mode 100644
index 0000000..2af840a
--- /dev/null
+++ b/installer/styles.css
@@ -0,0 +1,186 @@
+
+body {
+  margin: 1em 2em 2em 2em;
+  background-color: #fff;
+}
+
+body, td, th, div, p {
+  font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
+  font-size: small;
+  color: #000;
+}
+
+#banner {
+  position: relative;
+}
+
+#header {
+  position: relative;
+  height: 56px;
+  background: url('images/banner_bg.gif') top left repeat-x #fff;
+}
+
+#header div.banner-logo {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  width: 200px;
+  height: 56px;
+}
+
+#header div.banner-right {
+  position: absolute;
+  right: 0px;
+  top: 0px;
+  width: 10px;
+  height: 56px;
+}
+
+#topnav {
+  position: absolute;
+  right: 20px;
+  bottom: 8px;
+  text-align: right;
+  color: #ebebeb;
+  font-size: smaller;
+}
+
+#topnav a {
+  color: #ebebeb;
+  font-size: 11px;
+  text-decoration: none;
+}
+
+#topnav a:hover {
+  text-decoration: underline;
+}
+
+#content {
+  margin: 8px 20px;
+}
+
+#footer {
+  margin: 2em 20px 1em 20px;
+  padding-top: 0.6em;
+  font-size: smaller;
+  text-align: center;
+  border-top: 1px dotted #999;
+}
+
+#progress {
+  margin-bottom: 2em;
+  border: 1px solid #aaa;
+  background-color: #f9f9f9;
+}
+
+#progress:after {
+  content: ".";
+  display: block;
+  height: 0;
+  font-size: 0;
+  clear: both;
+  visibility: hidden;
+}
+
+#progress li {
+  float: left;
+  color: #999;
+  padding: 1em 5em 1em 0.2em;
+}
+
+#progress li.current {
+  color: #000;
+  font-weight: bold;
+}
+
+#progress li.passed,
+#progress li.passed a {
+  color: #333;
+  text-decoration: none;
+}
+
+#progress li.passed a:hover {
+  text-decoration: underline;
+}
+
+fieldset {
+  margin-bottom: 2em;
+  border: 1px solid #aaa;
+  background-color: #f9f9f9;
+}
+
+fieldset p.hint {
+  margin-top: 0.5em;
+}
+
+legend {
+  font-size: 1.1em;
+  font-weight: bold;
+}
+
+textarea.configfile {
+  background-color: #f9f9f9;
+  font-family: monospace;
+  font-size: 9pt;
+  width: 100%;
+  height: 40em;
+}
+
+dt.propname {
+  font-family: monospace;
+  font-size: 9pt;
+  margin-top: 1em;
+  margin-bottom: 0.6em;
+}
+
+dd div {
+  margin-top: 0.3em;
+}
+
+label {
+  padding-left: 0.5em;
+}
+
+th {
+  text-align: left;
+}
+
+h4 {
+  margin-bottom: 0.2em;
+}
+
+.hint {
+  color: #666;
+  font-size: 0.95em;
+}
+
+.success {
+  color: #006400;
+  font-weight: bold !important;
+}
+
+.fail {
+  color: #ff0000 !important;
+  font-weight: bold !important;
+}
+
+.na {
+  color: #f60;
+  font-weight: bold;
+}
+
+.indent {
+  padding-left: 0.8em;
+}
+
+.notice {
+  padding: 1em;
+  background-color: #f7fdcb;
+  border: 2px solid #c2d071;
+}
+
+.warning {
+  padding: 1em;
+  background-color: #ef9398;
+  border: 2px solid #dc5757;
+}
diff --git a/installer/test.php b/installer/test.php
new file mode 100644
index 0000000..254144e
--- /dev/null
+++ b/installer/test.php
@@ -0,0 +1,21 @@
+<form action="index.php" method="get">
+<input type="hidden" name="_step" value="3" />
+<?php
+
+echo '<p>[do some tests as in check.php-dist here]</p>';
+
+echo '<input type="submit" value="EXECUTE TESTS" />';
+
+?>
+</form>
+
+<p class="warning">
+
+After completing the installation and the final tests please <b>remove</b> the whole
+installer folder from the document root of the webserver.<br />
+<br />
+
+These files may expose sensitive configuration data like server passwords and encryption keys
+to the public. Make sure you cannot access this installer from your browser.
+
+</p>
diff --git a/installer/welcome.html b/installer/welcome.html
new file mode 100644
index 0000000..2fec0db
--- /dev/null
+++ b/installer/welcome.html
@@ -0,0 +1,14 @@
+<form action="index.php" methond="get">
+<input type="hidden" name="_step" value="1" />
+
+<p>Welcome to the interactive install script for the RoundCube Webmail package</p>
+<p>First let's check your local environment and find out if everything RoundCube needs is available.</p>
+
+<p>The basic requirements are:</p>
+<ul>
+  <li></li>
+</ul>
+
+<input type="submit" value="START" />
+
+</form>

--
Gitblit v1.9.1