From: Evan Prodromou Date: Fri, 10 Jun 2011 20:50:15 +0000 (-0400) Subject: Merge branch 'statusnetworkapi' into 1.0.x X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=331d8a99ba432cb7a9b5d3184b1ed97410a4d15a;p=quix0rs-gnu-social.git Merge branch 'statusnetworkapi' into 1.0.x --- 331d8a99ba432cb7a9b5d3184b1ed97410a4d15a diff --cc plugins/DomainStatusNetwork/lib/domainstatusnetworkinstaller.php index 0000000000,b2042abe94..b2e988b5e1 mode 000000,100644..100644 --- a/plugins/DomainStatusNetwork/lib/domainstatusnetworkinstaller.php +++ b/plugins/DomainStatusNetwork/lib/domainstatusnetworkinstaller.php @@@ -1,0 -1,318 +1,349 @@@ + . + * + * @category DomainStatusNetwork + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + + if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); + } + + /** + * Installer class for domain-based multi-homing systems + * + * @category DomainStatusNetwork + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + class DomainStatusNetworkInstaller extends Installer + { + protected $domain = null; + protected $rootname = null; + protected $sitedb = null; + protected $rootpass = null; + protected $nickname = null; + protected $sn = null; + + public $verbose = false; + + function __construct($domain) + { + $this->domain = $domain; + } + + /** + * Go for it! + * @return boolean success + */ + function main() + { + // We don't check prereqs. Check 'em before setting up a + // multi-home system, kthxbi + if ($this->prepare()) { + return $this->handle(); + } else { + $this->showHelp(); + return false; + } + } + + /** + * Get our input parameters... + * @return boolean success + */ + function prepare() + { + $config = $this->getConfig(); + + $this->nickname = DomainStatusNetworkPlugin::nicknameForDomain($this->domain); + + // XXX make this configurable + + $this->sitename = sprintf('The %s Status Network', $this->domain); + + $this->server = $this->nickname.'.'.$config['WILDCARD']; + $this->path = null; + $this->fancy = true; + + $datanick = $this->databaseize($this->nickname); + + $this->host = $config['DBHOSTNAME']; + $this->database = $datanick.$config['DBBASE']; + $this->dbtype = 'mysql'; // XXX: support others... someday + $this->username = $datanick.$config['USERBASE']; + + // Max size for MySQL + + if (strlen($this->username) > 16) { + $this->username = sprintf('%s%08x', substr($this->username, 0, 8), crc32($this->username)); + } + + $pwgen = $config['PWDGEN']; + + $password = `$pwgen`; + + $this->password = trim($password); + + // For setting up the database + + $this->rootname = $config['ADMIN']; + $this->rootpass = $config['ADMINPASS']; + $this->sitehost = $config['DBHOST']; + $this->sitedb = $config['SITEDB']; + ++ $tagstr = $config['TAGS']; ++ ++ if (!empty($tagstr)) { ++ $this->tags = preg_split('/[\s,]+/', $tagstr); ++ } else { ++ $this->tags = array(); ++ } ++ + // Explicitly empty + + $this->adminNick = null; + $this->adminPass = null; + $this->adminEmail = null; + $this->adminUpdates = null; + + /** Should we skip writing the configuration file? */ + $this->skipConfig = true; + + if (!$this->validateDb()) { + return false; + } + + return true; + } + + function handle() + { + return $this->doInstall(); + } + + function setupDatabase() + { + $this->updateStatus('Creating database...'); + $this->createDatabase(); + parent::setupDatabase(); + $this->updateStatus('Creating file directories...'); + $this->createDirectories(); + $this->updateStatus('Saving status network...'); + $this->saveStatusNetwork(); + $this->updateStatus('Checking schema for plugins...'); + $this->checkSchema(); + } + + function saveStatusNetwork() + { + Status_network::setupDB($this->sitehost, + $this->rootname, + $this->rootpass, + $this->sitedb, array()); + + $sn = new Status_network(); + + $sn->nickname = $this->nickname; + $sn->dbhost = $this->host; + $sn->dbuser = $this->username; + $sn->dbpass = $this->password; + $sn->dbname = $this->database; + $sn->sitename = $this->sitename; + + $result = $sn->insert(); + + if (!$result) { + throw new ServerException("Could not create status_network: " . print_r($sn, true)); + } + + // Re-fetch; stupid auto-increment integer isn't working + + $sn = Status_network::staticGet('nickname', $sn->nickname); + + if (empty($sn)) { + throw new ServerException("Created {$this->nickname} status_network and could not find it again."); + } + - $sn->setTags(array('domain='.$this->domain)); ++ // Set default tags ++ ++ $tags = $this->tags; ++ ++ // Add domain tag ++ ++ $tags[] = 'domain='.$this->domain; ++ ++ $sn->setTags($tags); + + $this->sn = $sn; + } + + function checkSchema() + { + $config = $this->getConfig(); + + Status_network::$wildcard = $config['WILDCARD']; + + StatusNet::switchSite($this->nickname); + ++ // We need to initialize the schema_version stuff to make later setup easier ++ ++ $schema = array(); ++ require INSTALLDIR.'/db/core.php'; ++ $tableDefs = $schema; ++ ++ $schema = Schema::get(); ++ $schemaUpdater = new SchemaUpdater($schema); ++ ++ foreach ($tableDefs as $table => $def) { ++ $schemaUpdater->register($table, $def); ++ } ++ ++ $schemaUpdater->checkSchema(); ++ + Event::handle('CheckSchema'); + } + + function getStatusNetwork() + { + return $this->sn; + } + + function createDirectories() + { + $config = $this->getConfig(); + + foreach (array('AVATARBASE', 'BACKGROUNDBASE', 'FILEBASE') as $key) { + $base = $config[$key]; + $dirname = $base.'/'.$this->nickname; + + // Make sure our bits are set + $mask = umask(0); + mkdir($dirname, 0770, true); + umask($mask); + + // If you set the setuid bit on your base dirs this should be + // unnecessary, but just in case. You must be root for this + // to work. + + if (array_key_exists('WEBUSER', $config)) { + chown($dirname, $config['WEBUSER']); + } + if (array_key_exists('WEBGROUP', $config)) { + chgrp($dirname, $config['WEBGROUP']); + } + } + } + + function createDatabase() + { + // Create the New DB + $res = mysql_connect($this->host, $this->rootname, $this->rootpass); + if (!$res) { + throw new ServerException("Cannot connect to {$this->host} as {$this->rootname}."); + } + + mysql_query("CREATE DATABASE ". mysql_real_escape_string($this->database), $res); + + $return = mysql_select_db($this->database, $res); + + if (!$return) { + throw new ServerException("Unable to connect to {$this->database} on {$this->host}."); + } + + foreach (array('localhost', '%') as $src) { + mysql_query("GRANT ALL ON " . + mysql_real_escape_string($this->database).".* TO '" . + $this->username . "'@'".$src."' ". + "IDENTIFIED BY '".$this->password."'", $res); + } + + mysql_close($res); + } + + function getConfig() + { + static $config; + + $cfg_file = "/etc/statusnet/setup.cfg"; + + if (empty($config)) { + $result = parse_ini_file($cfg_file); + + $config = array(); + foreach ($result as $key => $value) { + $key = str_replace('export ', '', $key); + $config[$key] = $value; + } + } + + return $config; + } + + function showHelp() + { + } + + function warning($message, $submessage='') + { + print $this->html2text($message) . "\n"; + if ($submessage != '') { + print " " . $this->html2text($submessage) . "\n"; + } + print "\n"; + } + + function updateStatus($status, $error=false) + { + if ($this->verbose || $error) { + if ($error) { + print "ERROR: "; + } + print $this->html2text($status); + print "\n"; + } + } + + private function html2text($html) + { + // break out any links for text legibility + $breakout = preg_replace('/+]\bhref="(.*)"[^>]*>(.*)<\/a>/', + '\2 <\1>', + $html); + return html_entity_decode(strip_tags($breakout), ENT_QUOTES, 'UTF-8'); + } + + function databaseize($nickname) + { + $nickname = str_replace('-', '_', $nickname); + return $nickname; + } + }