Example #1
0
function _getInputValidationErrors($mySqlColsAndTypes, $newRecordValues)
{
    global $schema, $tableName, $escapedTableName, $CURRENT_USER, $isMyAccountMenu;
    $errors = '';
    $recordNum = @$_REQUEST['num'];
    // load schema columns
    foreach ($schema as $fieldname => $fieldSchema) {
        if (!is_array($fieldSchema)) {
            continue;
        }
        // fields are stored as arrays, other entries are table metadata
        if (!userHasFieldAccess($fieldSchema)) {
            continue;
        }
        // skip fields that the user has no access to
        if ($tableName == 'accounts' && $fieldname == 'isAdmin' && !$CURRENT_USER['isAdmin']) {
            continue;
        }
        // skip admin only fields
        if ($isMyAccountMenu && @(!$fieldSchema['myAccountField'])) {
            continue;
        }
        // skip validation on fields that aren't displayed
        $isMyAccountPasswordField = $isMyAccountMenu && $fieldname == 'password';
        $value = @$newRecordValues[$fieldname];
        $labelOrName = @$fieldSchema['label'] != '' ? $fieldSchema['label'] : $fieldname;
        // date fields - check if required suffixes are missing
        $missingDateSubfields = 0;
        $partialDateEntered = false;
        if (@$fieldSchema['type'] == 'date') {
            $requiredDateSuffixes = array('mon', 'day', 'year');
            if ($fieldSchema['showTime']) {
                if ($fieldSchema['use24HourFormat']) {
                    array_push($requiredDateSuffixes, 'hour24', 'min');
                } else {
                    array_push($requiredDateSuffixes, 'hour12', 'min', 'isPM');
                }
                if ($fieldSchema['showSeconds']) {
                    array_push($requiredDateSuffixes, 'sec');
                }
            }
            $subFieldCount = 0;
            foreach ($requiredDateSuffixes as $suffix) {
                if (@$_REQUEST["{$fieldname}:{$suffix}"] == '') {
                    $missingDateSubfields++;
                }
            }
            $partialDateEntered = $missingDateSubfields && count($requiredDateSuffixes) > $missingDateSubfields;
            // if some but not all date subfields entered then require all of them
        }
        // check required fields
        $checkRequired = @$fieldSchema['isRequired'] && !$isMyAccountPasswordField || $partialDateEntered;
        if ($checkRequired) {
            if ($fieldSchema['type'] == 'upload') {
                if (!getUploadCount($tableName, $fieldname, @$_REQUEST['num'], @$_REQUEST['preSaveTempId'])) {
                    $errors .= sprintf(t("'%s' is required! You must upload a file!"), $labelOrName) . "\n";
                }
            } elseif ($fieldSchema['type'] == 'date') {
                if ($partialDateEntered) {
                    $errors .= sprintf(t("Please fill out all '%s' fields!"), $labelOrName) . "\n";
                } elseif ($missingDateSubfields) {
                    $errors .= sprintf(t("'%s' is required!"), $labelOrName) . "\n";
                }
            } elseif ($value == '') {
                $errors .= sprintf(t("'%s' is required!"), $labelOrName) . "\n";
            }
        }
        // check for unique fields
        if (@$fieldSchema['isUnique'] && $value != '') {
            // unique allows blank fields (use required to require value)
            $errors .= __getUniqueFieldErrors($labelOrName, $fieldname, $value, $recordNum);
        }
        // get length of content
        if (@$fieldSchema['type'] == 'wysiwyg') {
            $textOnlyValue = strip_tags($value);
            $textOnlyValue = preg_replace('/\\s+/', ' ', $textOnlyValue);
            $textLength = mb_strlen($textOnlyValue);
        } elseif (@$fieldSchema['type'] == 'textbox' && @$fieldSchema['autoFormat']) {
            $textOnlyValue = str_replace("<br/>\n", "\n", $value);
            $textLength = mb_strlen($textOnlyValue);
        } else {
            $textLength = mb_strlen($value);
        }
        // check min/max length of content
        if ($value != '' && @$fieldSchema['minLength'] && $textLength < $fieldSchema['minLength']) {
            $errors .= sprintf(t('\'%1$s\' must be at least %2$s characters! (currently %3$s characters)'), $labelOrName, $fieldSchema['minLength'], $textLength) . "\n";
        }
        if ($value != '' && @$fieldSchema['maxLength'] && $textLength > $fieldSchema['maxLength']) {
            $errors .= sprintf(t('\'%1$s\' cannot be longer than %2$s characters! (currently %3$s characters)'), $labelOrName, $fieldSchema['maxLength'], $textLength) . "\n";
        }
        // check allowed/disallowed characters (skip if $fieldSchema['charset'] is blank to avoid: "Warning: preg_match(): Compilation failed: missing terminating ]")
        if (strlen(@$fieldSchema['charset']) > 0) {
            $allowRegexp = '/[^' . preg_quote(@$fieldSchema['charset'], '/') . ']/';
            $disallowRegexp = '/[' . preg_quote(@$fieldSchema['charset'], '/') . ']/';
            if (@$fieldSchema['charsetRule'] == 'allow' && preg_match($allowRegexp, $value)) {
                $errors .= sprintf(t('\'%1$s\' only allows the following characters (%2$s)'), $labelOrName, $fieldSchema['charset']) . "\n";
            }
            if (@$fieldSchema['charsetRule'] == 'disallow' && preg_match($disallowRegexp, $value)) {
                $errors .= sprintf(t('\'%1$s\' doesn\'t allow the following characters (%2$s)'), $labelOrName, $fieldSchema['charset']) . "\n";
            }
        }
        // custom field error checking
        if (@$schema['menuType'] == 'category' && $fieldname == 'parentNum') {
            // load parent category
            $escapedNum = mysql_escape($value);
            $query = "SELECT num, name, lineage FROM `{$escapedTableName}` WHERE num = '{$escapedNum}' LIMIT 1";
            $result = mysql_query($query) or die("MySQL Error: " . mysql_error() . "\n");
            $parentCategory = mysql_fetch_assoc($result);
            if (is_resource($result)) {
                mysql_free_result($result);
            }
            // error checking
            if (preg_match("/:{$recordNum}:/", $parentCategory['lineage'])) {
                $errors .= sprintf(t('\'%s\' can\'t select the current category or any categories under the current category!'), $labelOrName) . "\n";
            }
        }
        // my account - password changing
        $newPasswordEntered = @$_REQUEST['password:old'] || @$_REQUEST['password'] || @$_REQUEST['password:again'];
        if ($isMyAccountPasswordField && $newPasswordEntered && !$errors) {
            $_REQUEST['password:old'] = preg_replace("/^\\s+|\\s+\$/s", '', @$_REQUEST['password:old']);
            // v2.52 remove leading and trailing whitespace
            $oldPasswordHash = getPasswordDigest(@$_REQUEST['password:old']);
            if (!@$_REQUEST['password:old']) {
                $errors .= t("Please specify your current password!") . "\n";
            } else {
                if ($oldPasswordHash != getPasswordDigest($CURRENT_USER['password'])) {
                    $errors .= t("Current password is not correct!") . "\n";
                }
            }
            // v2.51 works when comparing hashed and unhashed passwords the same
            $errors .= getNewPasswordErrors(@$_REQUEST['password'], @$_REQUEST['password:again'], $CURRENT_USER['username']);
            // v2.52
        }
        // accounts - password changing (usually done by admin) v2.52
        if (!$isMyAccountMenu && $tableName == 'accounts' && $fieldname == 'password' && !$errors) {
            $errors .= getNewPasswordErrors(@$_REQUEST['password'], null, @$newRecordValues['username']);
            // v2.52
        }
        // user accounts - don't allow disabling of own account
        if ($tableName == 'accounts' && $fieldname == 'disabled') {
            if ($recordNum == $CURRENT_USER['num'] && !empty($_REQUEST['disabled'])) {
                $errors .= t("You cannot disable your own account!") . "\n";
            }
        }
    }
    //
    return $errors;
}
function resetPassword()
{
    global $CURRENT_USER, $SETTINGS;
    $GLOBALS['sentEmail'] = false;
    // error checking
    if (!@$_REQUEST['userNum']) {
        die("No 'userNum' value specified!");
    }
    if (!@$_REQUEST['resetCode']) {
        die("No 'resetCode' value specified!");
    }
    if (!_isValidPasswordResetCode(@$_REQUEST['userNum'], @$_REQUEST['resetCode'])) {
        alert(t("Password reset code has expired or is not valid. Try resetting your password again."));
        showInterface('forgotPassword.php', false);
    }
    // load user
    global $user;
    $user = mysql_get(accountsTable(), (int) @$_REQUEST['userNum']);
    // Lookup username or email
    if (@$_REQUEST['submitForm']) {
        security_dieUnlessPostForm();
        security_dieOnInvalidCsrfToken();
        disableInDemoMode('', 'resetPassword.php');
        // error checking
        $textErrors = getNewPasswordErrors(@$_REQUEST['password'], @$_REQUEST['password:again'], $user['username']);
        // v2.52
        if ($textErrors) {
            alert(nl2br(htmlencode($textErrors)));
            showInterface('resetPassword.php');
            exit;
        }
        // update password
        $newPassword = getPasswordDigest($_REQUEST['password']);
        mysql_update(accountsTable(), $user['num'], null, array('password' => $newPassword));
        // show login
        alert(t('Password updated!'));
        $_REQUEST = array();
        showInterface('login.php', false);
        exit;
    }
    //
    showInterface('resetPassword.php');
    exit;
}
function installIfNeeded()
{
    global $SETTINGS, $APP, $TABLE_PREFIX;
    if (isInstalled()) {
        return;
    }
    // skip if already installed
    // rename default files
    renameOrRemoveDefaultFiles();
    // error checking
    if ($SETTINGS['uploadDir'] && !is_dir($SETTINGS['uploadDir'])) {
        print "Upload directory doesn't exist, please update 'uploadDir' in /data/" . SETTINGS_FILENAME . "<br/>\n";
        print "Current uploadDir value: " . htmlencode($SETTINGS['uploadDir']) . "<br/>\n";
        print "Suggested uploadDir value: uploads/ or ../uploads/<br/>\n";
        exit;
    }
    // error checking
    checkFilePermissions();
    // display license
    if (@$_REQUEST['menu'] == 'license') {
        showInterface('license.php');
    }
    // save
    if (@$_REQUEST['save']) {
        // error checking
        if (!$_REQUEST['licenseCompanyName']) {
            alert("Please enter your 'Company Name'<br/>\n");
        }
        if (!$_REQUEST['licenseDomainName']) {
            alert("Please enter your 'Domain Name'<br/>\n");
        }
        if (!$_REQUEST['licenseProductId']) {
            alert("Please enter your 'Product Id'<br/>\n");
        } else {
            if (!isValidProductId($_REQUEST['licenseProductId'])) {
                alert("Invalid Product Id!<br/>\n");
            }
        }
        if (!$_REQUEST['agreeToOneInstall']) {
            alert("Please check 'I agree not to use this 'Product Id' for multiple installs'<br/>\n");
        }
        if (!$_REQUEST['understandTermination']) {
            alert("Please check 'I understand doing so may cause be to lose my right to use this software'<br/>\n");
        }
        if (!$_REQUEST['agreeToLicense']) {
            alert("Please check 'I accept the terms of the License Agreement'<br/>\n");
        }
        if (!$_REQUEST['mysqlHostname']) {
            alert("Please enter your 'MySQL Hostname'<br/>\n");
        }
        if (!$_REQUEST['mysqlDatabase']) {
            alert("Please enter your 'MySQL Database'<br/>\n");
        }
        if (!$_REQUEST['mysqlUsername']) {
            alert("Please enter your 'MySQL Username'<br/>\n");
        }
        if (!$_REQUEST['mysqlTablePrefix']) {
            alert("Please enter your 'MySQL Table Prefix'<br/>\n");
        } elseif (preg_match("/[A-Z]/", $_REQUEST['mysqlTablePrefix'])) {
            alert("Value for 'MySQL Table Prefix' must be lowercase.<br/>\n");
        } elseif (!preg_match("/^[a-z]/i", $_REQUEST['mysqlTablePrefix'])) {
            alert("Value for 'MySQL Table Prefix' must start with a letter.<br/>\n");
        } elseif (!preg_match("/_\$/", $_REQUEST['mysqlTablePrefix'])) {
            alert("Value for 'MySQL Table Prefix' must end in underscore.<br/>\n");
        }
        // New Installation
        if (!@$_REQUEST['restoreFromBackup']) {
            if (!$_REQUEST['adminFullname']) {
                alert("Please enter 'Admin Full Name'<br/>\n");
            }
            if (!$_REQUEST['adminEmail']) {
                alert("Please enter 'Admin Email'<br/>\n");
            } elseif (!isValidEmail($_REQUEST['adminEmail'])) {
                alert("Please enter a valid email for 'Admin Email' (Example: user@example.com)<br/>\n");
            }
            if (!$_REQUEST['adminUsername']) {
                alert("Please enter 'Admin Username'<br/>\n");
            }
            $passwordErrors = getNewPasswordErrors($_REQUEST['adminPassword1'], $_REQUEST['adminPassword2'], $_REQUEST['adminUsername']);
            // v2.52
            if ($passwordErrors) {
                alert(nl2br(htmlencode($passwordErrors)));
            }
        }
        // Restore from Backup
        if (@$_REQUEST['restoreFromBackup']) {
            if (!$_REQUEST['restore']) {
                alert("Please select a backup file to restore<br/>\n");
            }
        }
        // Advanced - v2.53
        if (!@$_REQUEST['useCustomSettingsFile']) {
            if (is_file(SETTINGS_DEV_FILEPATH)) {
                alert(t("You must select 'Use Custom Settings File' since a custom settings file for this domain already exists!") . "<br/>\n");
            } elseif (isDevServer()) {
                alert("This is a development server, you must select 'Use Custom Settings File'." . "<br/>\n");
            }
        }
        if (@$_REQUEST['webPrefixUrl'] != '') {
            if (!preg_match("|^(\\w+:/)?/|", $_REQUEST['webPrefixUrl'])) {
                alert(t("Website Prefix URL must start with /") . "<br/>\n");
            }
            if (preg_match("|/\$|", $_REQUEST['webPrefixUrl'])) {
                alert(t("Website Prefix URL cannot end with /") . "<br/>\n");
            }
        }
        // update settings (not saved unless there are no errors)
        $SETTINGS['cookiePrefix'] = substr(md5(mt_rand()), 0, 5) . '_';
        //v2.51 shortened prefix so it's easy to see full cookie names in browser cookie list
        $SETTINGS['adminEmail'] = @$SETTINGS['adminEmail'] ? $SETTINGS['adminEmail'] : $_REQUEST['adminEmail'];
        $SETTINGS['licenseCompanyName'] = $_REQUEST['licenseCompanyName'];
        $SETTINGS['licenseDomainName'] = $_REQUEST['licenseDomainName'];
        $SETTINGS['licenseProductId'] = $_REQUEST['licenseProductId'];
        $SETTINGS['webRootDir'] = @$SETTINGS['webRootDir'] ? $SETTINGS['webRootDir'] : @$_SERVER['DOCUMENT_ROOT'];
        $SETTINGS['mysql']['hostname'] = $_REQUEST['mysqlHostname'];
        $SETTINGS['mysql']['database'] = $_REQUEST['mysqlDatabase'];
        $SETTINGS['mysql']['username'] = $_REQUEST['mysqlUsername'];
        $SETTINGS['mysql']['password'] = $_REQUEST['mysqlPassword'];
        $SETTINGS['mysql']['tablePrefix'] = $_REQUEST['mysqlTablePrefix'];
        $TABLE_PREFIX = $_REQUEST['mysqlTablePrefix'];
        // update TABLE_PREFIX global as well.
        $SETTINGS['webPrefixUrl'] = $_REQUEST['webPrefixUrl'];
        // display errors
        if (alert()) {
            require "lib/menus/install.php";
            exit;
        }
        // connect to mysql
        $errors = connectToMySQL('returnErrors');
        if ($errors) {
            alert($errors);
            require "lib/menus/install.php";
            exit;
        } else {
            connectToMySQL();
        }
        // create schema tables
        createMissingSchemaTablesAndFields();
        clearAlertsAndNotices();
        // don't show "created table/field" alerts
        // New Installation: check if admin user already exists
        if (!@$_REQUEST['restoreFromBackup']) {
            $passwordHash = getPasswordDigest($_REQUEST['adminPassword1']);
            $identicalUserExists = mysql_count('accounts', array('username' => $_REQUEST['adminUsername'], 'password' => $passwordHash, 'isAdmin' => '1'));
            if (!$identicalUserExists) {
                // if the don't exist, check if a user with the same username exists and show an error if they do
                $count = mysql_count('accounts', array('username' => $_REQUEST['adminUsername']));
                if (!$identicalUserExists && $count > 0) {
                    alert("Admin username already exists, please choose another.<br/>\n");
                }
            }
            // create admin user
            if (!$identicalUserExists && !alert()) {
                mysqlStrictMode(false);
                // disable Mysql strict errors for when a field isn't defined below (can be caused when fields are added later)
                mysql_query("INSERT INTO `{$TABLE_PREFIX}accounts` SET\n                          createdDate      = NOW(),\n                          createdByUserNum = '0',\n                          updatedDate      = NOW(),\n                          updatedByUserNum = '0',\n                          fullname         = '" . mysql_escape($_REQUEST['adminFullname']) . "', email    = '" . mysql_escape($_REQUEST['adminEmail']) . "',\n                          username         = '******'adminUsername']) . "', password = '******',\n                          disabled         = '0',\n                          isAdmin          = '1',\n                          expiresDate      = '0000-00-00 00:00:00',\n                          neverExpires     = '1'") or alert("MySQL Error Creating Admin User:<br/>\n" . htmlencode(mysql_error()) . "\n");
                // create accesslist entry
                mysql_query("INSERT INTO `{$TABLE_PREFIX}_accesslist` (userNum, tableName, accessLevel, maxRecords, randomSaveId)\n                          VALUES (LAST_INSERT_ID(), 'all', '9', NULL, '1234567890')") or alert("MySQL Error Creating Admin Access List:<br/>\n" . htmlencode(mysql_error()) . "\n");
            }
        }
        // Restore from Backup: Restore backup file
        if (@$_REQUEST['restoreFromBackup']) {
            $userCount = mysql_count('accounts');
            if ($userCount) {
                $userTable = $TABLE_PREFIX . 'accounts';
                $errorMessage = sprintf("Can't restore from backup because it would overwrite the %s existing user accounts in the specified database location.<br/>\n", $userCount);
                $errorMessage .= sprintf("Try changing the MySQL Database or Table Prefix to restore to a different location, or remove existing users from '%s'.<br/>\n", $userTable);
                alert($errorMessage);
            } else {
                // restore database
                $filename = @$_REQUEST['restore'];
                mysqlStrictMode(false);
                // disable Mysql strict errors
                restoreDatabase(DATA_DIR . '/backups/' . $filename);
                notice("Restored backup file /data/backups/{$filename}");
                makeAllUploadRecordsRelative();
            }
        }
        // save settings
        if (!alert()) {
            saveSettings(@$_REQUEST['useCustomSettingsFile']);
            isInstalled(true);
            // save installed status
            redirectBrowserToURL('?menu=home', true);
            // refresh page
            exitl;
        }
    }
    // set defaults
    if (!array_key_exists('licenseDomainName', $_REQUEST)) {
        $_REQUEST['licenseDomainName'] = $_SERVER['HTTP_HOST'];
    }
    if (!array_key_exists('mysqlHostname', $_REQUEST)) {
        $_REQUEST['mysqlHostname'] = $SETTINGS['mysql']['hostname'];
    }
    if (!array_key_exists('mysqlDatabase', $_REQUEST)) {
        $_REQUEST['mysqlDatabase'] = $SETTINGS['mysql']['database'];
    }
    if (!array_key_exists('mysqlUsername', $_REQUEST)) {
        $_REQUEST['mysqlUsername'] = $SETTINGS['mysql']['username'];
    }
    if (!array_key_exists('mysqlTablePrefix', $_REQUEST)) {
        $_REQUEST['mysqlTablePrefix'] = $SETTINGS['mysql']['tablePrefix'];
    }
    // show form
    require "lib/menus/install.php";
    exit;
}