/** * * * @param $Data * @param $Options * @return bool */ public static function check(&$Data, &$Options) { // Make the request. $Get = array(); if (isset($Data['IPAddress'])) { $AddIP = true; // Don't check against the localhost. foreach (array('127.0.0.1/0', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16') as $LocalCIDR) { if (Gdn_Statistics::cidrCheck($Data['IPAddress'], $LocalCIDR)) { $AddIP = false; break; } } if ($AddIP) { $Get['ip'] = $Data['IPAddress']; } } if (isset($Data['Username'])) { $Get['username'] = $Data['Username']; } if (isset($Data['Email'])) { $Get['email'] = $Data['Email']; } if (empty($Get)) { return false; } $Get['f'] = 'json'; $Url = "http://www.stopforumspam.com/api?" . http_build_query($Get); $Curl = curl_init(); curl_setopt($Curl, CURLOPT_URL, $Url); curl_setopt($Curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($Curl, CURLOPT_TIMEOUT, 4); curl_setopt($Curl, CURLOPT_FAILONERROR, 1); $ResultString = curl_exec($Curl); curl_close($Curl); if ($ResultString) { $Result = json_decode($ResultString, true); $IPFrequency = valr('ip.frequency', $Result, 0); $EmailFrequency = valr('email.frequency', $Result, 0); $IsSpam = false; // Flag registrations as spam above a certain threshold. if ($IPFrequency >= c('Plugins.StopForumSpam.IPThreshold1', 5) || $EmailFrequency >= c('Plugins.StopForumSpam.EmailThreshold1', 20)) { $IsSpam = true; } // Don't even log registrations that are above another threahold. if ($IPFrequency >= c('Plugins.StopForumSpam.IPThreshold2', 20) || $EmailFrequency >= c('Plugins.StopForumSpam.EmailThreshold2', 50)) { $Options['Log'] = false; } if ($Result) { $Data['_Meta']['IP Frequency'] = $IPFrequency; $Data['_Meta']['Email Frequency'] = $EmailFrequency; } return $IsSpam; } return false; }
public function Index() { $this->Permission('Garden.Settings.Manage'); $this->AddSideMenu('dashboard/statistics'); //$this->AddJsFile('statistics.js'); $this->Title(T('Vanilla Statistics')); $this->EnableSlicing($this); if ($this->Form->IsPostBack()) { $Flow = TRUE; if ($Flow && $this->Form->GetFormValue('ClearCredentials')) { Gdn::InstallationID(FALSE); Gdn::InstallationSecret(FALSE); Gdn::Statistics()->Tick(); $Flow = FALSE; } if ($Flow && $this->Form->GetFormValue('SaveIdentity')) { Gdn::InstallationID($this->Form->GetFormValue('InstallationID')); Gdn::InstallationSecret($this->Form->GetFormValue('InstallationSecret')); $this->InformMessage(T("Your settings have been saved.")); } if ($Flow && $this->Form->GetFormValue('AllowLocal')) { SaveToConfig('Garden.Analytics.AllowLocal', TRUE); } if ($Flow && $this->Form->GetFormValue('Allow')) { SaveToConfig('Garden.Analytics.Enabled', TRUE); } } $AnalyticsEnabled = Gdn_Statistics::CheckIsEnabled(); if ($AnalyticsEnabled) { $ConfFile = PATH_LOCAL_CONF.DS.'config.php'; $this->SetData('ConfWritable', $ConfWritable = is_writable($ConfFile)); if (!$ConfWritable) $AnalyticsEnabled = FALSE; } $this->SetData('AnalyticsEnabled', $AnalyticsEnabled); $NotifyMessage = Gdn::Get('Garden.Analytics.Notify', FALSE); $this->SetData('NotifyMessage', $NotifyMessage); if ($NotifyMessage !== FALSE) Gdn::Set('Garden.Analytics.Notify', NULL); $this->Form->SetFormValue('InstallationID', Gdn::InstallationID()); $this->Form->SetFormValue('InstallationSecret', Gdn::InstallationSecret()); $this->Render(); }
/** * Statistics setup & configuration. * * @since 2.0.17 * @access public */ public function index() { $this->permission('Garden.Settings.Manage'); $this->addSideMenu('dashboard/statistics'); //$this->addJsFile('statistics.js'); $this->title(t('Vanilla Statistics')); $this->enableSlicing($this); if ($this->Form->authenticatedPostBack()) { $Flow = true; if ($Flow && $this->Form->getFormValue('Reregister')) { Gdn::Statistics()->register(); } if ($Flow && $this->Form->getFormValue('Save')) { Gdn::installationID($this->Form->getFormValue('InstallationID')); Gdn::installationSecret($this->Form->getFormValue('InstallationSecret')); $this->informMessage(t("Your settings have been saved.")); } if ($Flow && $this->Form->getFormValue('AllowLocal')) { saveToConfig('Garden.Analytics.AllowLocal', true); } if ($Flow && $this->Form->getFormValue('Allow')) { saveToConfig('Garden.Analytics.Enabled', true); } if ($Flow && $this->Form->getFormValue('ClearCredentials')) { Gdn::installationID(false); Gdn::installationSecret(false); Gdn::statistics()->Tick(); $Flow = false; } } else { $this->Form->setValue('InstallationID', Gdn::installationID()); $this->Form->setValue('InstallationSecret', Gdn::installationSecret()); } $AnalyticsEnabled = Gdn_Statistics::checkIsEnabled(); if ($AnalyticsEnabled) { $ConfFile = Gdn::config()->defaultPath(); $this->setData('ConfWritable', $ConfWritable = is_writable($ConfFile)); if (!$ConfWritable) { $AnalyticsEnabled = false; } } $this->setData('AnalyticsEnabled', $AnalyticsEnabled); $NotifyMessage = Gdn::get('Garden.Analytics.Notify', false); $this->setData('NotifyMessage', $NotifyMessage); if ($NotifyMessage !== false) { Gdn::set('Garden.Analytics.Notify', null); } $this->render(); }
/** * Override the default index method of the settings controller in the * dashboard application to render new statistics. */ public function StatsDashboard($Sender) { $StatsUrl = $this->AnalyticsServer; if (!StringBeginsWith($StatsUrl, 'http:')) { $StatsUrl = "http://{$StatsUrl}"; } // Tell the page where to find the Vanilla Analytics provider $Sender->AddDefinition('VanillaStatsUrl', $StatsUrl); $Sender->SetData('VanillaStatsUrl', $StatsUrl); // Load javascript & css, check permissions, and load side menu for this page. $Sender->AddJsFile('settings.js'); $Sender->Title(T('Dashboard')); $Sender->RequiredAdminPermissions[] = 'Garden.Settings.Manage'; $Sender->RequiredAdminPermissions[] = 'Garden.Routes.Manage'; $Sender->RequiredAdminPermissions[] = 'Garden.Applications.Manage'; $Sender->RequiredAdminPermissions[] = 'Garden.Plugins.Manage'; $Sender->RequiredAdminPermissions[] = 'Garden.Themes.Manage'; $Sender->RequiredAdminPermissions[] = 'Garden.Registration.Manage'; $Sender->RequiredAdminPermissions[] = 'Garden.Applicants.Manage'; $Sender->RequiredAdminPermissions[] = 'Garden.Roles.Manage'; $Sender->RequiredAdminPermissions[] = 'Garden.Users.Add'; $Sender->RequiredAdminPermissions[] = 'Garden.Users.Edit'; $Sender->RequiredAdminPermissions[] = 'Garden.Users.Delete'; $Sender->RequiredAdminPermissions[] = 'Garden.Users.Approve'; $Sender->FireEvent('DefineAdminPermissions'); $Sender->Permission($Sender->RequiredAdminPermissions, '', FALSE); $Sender->AddSideMenu('dashboard/settings'); if (!Gdn_Statistics::CheckIsEnabled() && Gdn_Statistics::CheckIsLocalhost()) { $Sender->Render('dashboardlocalhost', '', 'plugins/VanillaStats'); } else { $Sender->AddJsFile('plugins/VanillaStats/js/vanillastats.js'); $Sender->AddJsFile('plugins/VanillaStats/js/picker.js'); $Sender->AddCSSFile('plugins/VanillaStats/design/style.css'); $Sender->AddCSSFile('plugins/VanillaStats/design/picker.css'); $this->ConfigureRange($Sender); $VanillaID = Gdn::InstallationID(); $Sender->SetData('VanillaID', $VanillaID); $Sender->SetData('VanillaVersion', APPLICATION_VERSION); $Sender->SetData('SecurityToken', $this->SecurityToken()); // Render the custom dashboard view $Sender->Render('dashboard', '', 'plugins/VanillaStats'); } }
/** * Load up the leaderboard module data based on a specific time slot * * @param string $SlotType Valid options are 'a': All Time, 'w': Weekly, 'm': * Monthly, 'y': Yearly */ public function GetData($SlotType = 'a') { // Get the leaderboard data $Leaders = Gdn::SQL()->Select('up.Points as YagaPoints, u.*')->From('User u')->Join('UserPoints up', 'u.UserID = up.UserID')->Where('up.SlotType', $SlotType)->Where('up.TimeSlot', gmdate('Y-m-d', Gdn_Statistics::TimeSlotStamp($SlotType)))->Where('up.Source', 'Total')->OrderBy('up.Points', 'desc')->Limit(C('Yaga.LeaderBoard.Limit', 10), 0)->Get()->Result(); $this->Data = $Leaders; switch ($SlotType) { case 'a': $this->Title = T('Yaga.LeaderBoard.AllTime'); break; case 'w': $this->Title = T('Yaga.LeaderBoard.Week'); break; case 'm': $this->Title = T('Yaga.LeaderBoard.Month'); break; case 'y': $this->Title = T('Yaga.LeaderBoard.Year'); break; } }
/** * Signature check * * This method checks the supplied signature of a request against a hash of * the request arguments augmented with the local secret from the config file. * ***** * THIS METHOD USES ALL SUPPLIED ARGUMENTS IN ITS SIGNATURE HASH ALGORITHM ***** * * @param type $Request Array of request parameters * @return boolean Status of verification check, or null if no VanillaID */ protected function VerifySignature($Request) { // If this response has no ID, return NULL (could not verify) $VanillaID = GetValue('VanillaID', $Request, NULL); if (is_null($VanillaID)) { return NULL; } // Response is bogus - wrong InstallationID if (!is_null(Gdn::InstallationID()) && $VanillaID != Gdn::InstallationID()) { return FALSE; } // If we don't have a secret, we cannot verify anyway $VanillaSecret = Gdn::InstallationSecret(); if (is_null($VanillaSecret)) { return NULL; } // Calculate clock desync $CurrentGmTime = Gdn_Statistics::Time(); $RequestTime = GetValue('RequestTime', $Request, 0); $TimeDiff = abs($CurrentGmTime - $RequestTime); $AllowedTimeDiff = C('Garden.Analytics.RequestTimeout', 1440); // Allow 24* minutes of clock desync, otherwise signature is invalid if ($TimeDiff > $AllowedTimeDiff) { return FALSE; } $SecurityHash = GetValue('SecurityHash', $Request); // Remove the existing SecuritHash before calculating the signature unset($Request['SecurityHash']); // Add the real secret $Request['Secret'] = $VanillaSecret; $SignData = array_intersect_key($Request, array_fill_keys(array('VanillaID', 'Secret', 'RequestTime', 'TimeSlot'), NULL)); // ksort the array to preserve a known order $SignData = array_change_key_case($SignData, CASE_LOWER); ksort($SignData); // Calculate the hash $RealHash = sha1(http_build_query($SignData)); if ($RealHash == $SecurityHash) { return TRUE; } return FALSE; }
/** * Add points to a user's total in a specific time slot. * * @param int $UserID * @param int $Points * @param string $SlotType * @param string $Source * @param int $CategoryID * @param int|false $Timestamp * @since 2.1.0 * @see UserModel::GivePoints() */ private static function givePointsInternal($UserID, $Points, $SlotType, $Source = 'Total', $CategoryID = 0, $Timestamp = false) { $TimeSlot = gmdate('Y-m-d', Gdn_Statistics::timeSlotStamp($SlotType, $Timestamp)); $Px = Gdn::database()->DatabasePrefix; $Sql = "insert {$Px}UserPoints (UserID, SlotType, TimeSlot, Source, CategoryID, Points)\n values (:UserID, :SlotType, :TimeSlot, :Source, :CategoryID, :Points)\n on duplicate key update Points = Points + :Points1"; Gdn::database()->query($Sql, [':UserID' => $UserID, ':Points' => $Points, ':SlotType' => $SlotType, ':Source' => $Source, ':CategoryID' => $CategoryID, ':TimeSlot' => $TimeSlot, ':Points1' => $Points]); }
/** * Add points to a user's total in a specific timeslot. * * @since 2.1.0 * @access protected * @see self::GivePoints */ protected static function _GivePoints($UserID, $Points, $SlotType, $Source = 'Total', $Timestamp = FALSE) { $TimeSlot = gmdate('Y-m-d', Gdn_Statistics::TimeSlotStamp($SlotType, $Timestamp)); $Px = Gdn::Database()->DatabasePrefix; $Sql = "insert {$Px}UserPoints (UserID, SlotType, TimeSlot, Source, Points)\n values (:UserID, :SlotType, :TimeSlot, :Source, :Points)\n on duplicate key update Points = Points + :Points1"; Gdn::Database()->Query($Sql, array(':UserID' => $UserID, ':Points' => $Points, ':SlotType' => $SlotType, ':Source' => $Source, ':TimeSlot' => $TimeSlot, ':Points1' => $Points)); }
#Content form .StatsDisabled input.Button { margin: 20px 0 0 0; } </style> <div class="StatsDisabled"> <strong><?php echo t("Vanilla Statistics are currently disabled"); ?> </strong> <?php if (!c('Garden.Analytics.Enabled', true)) { echo $this->Form->Hidden('Allow', array('value' => 1)); echo "<p>" . t("Garden.StatisticsDisabled", "You have specifically disabled Vanilla Statistics in your configuration file.") . "</p>"; echo $this->Form->button("Enable", array('class' => 'Button SliceSubmit')); } else { if (Gdn_Statistics::CheckIsLocalhost() && !c('Garden.Analytics.AllowLocal', false)) { echo $this->Form->Hidden('AllowLocal', array('value' => 1)); echo "<p>" . t("Garden.StatisticsLocal.Explain", "This forum appears to be running in a test environment, or is otherwise reporting a private IP. By default, forums running on private IPs are not tracked.") . "</p>"; echo "<p>" . t("Garden.StatisticsLocal.Resolve", "If you're sure your forum is accessible from the internet you can force it to report statistics here:") . "</p>"; echo $this->Form->button("Enable", array('class' => 'Button SliceSubmit')); } else { if (!$this->data('ConfWritable')) { echo "<p>" . t("Garden.StatisticsReadonly.Explain", "Your config.php file appears to be read-only. This means that Vanilla will be unable to automatically register your forum's InstallationID and InstallationSecret.") . "</p>"; echo "<p>" . t("Garden.StatisticsReadonly.Resolve", "To solve this problem, assign file mode 777 to your conf/config.php file.") . "</p>"; } } } ?> <p></p> </div>
/** * Override the default index method of the settings controller in the * dashboard application to render new statistics. */ public function statsDashboard($Sender) { $StatsUrl = $this->AnalyticsServer; if (!stringBeginsWith($StatsUrl, 'http:') && !stringBeginsWith($StatsUrl, 'https:')) { $StatsUrl = Gdn::request()->scheme() . "://{$StatsUrl}"; } // Tell the page where to find the Vanilla Analytics provider $Sender->addDefinition('VanillaStatsUrl', $StatsUrl); $Sender->setData('VanillaStatsUrl', $StatsUrl); // Load javascript & css, check permissions, and load side menu for this page. $Sender->addJsFile('settings.js'); $Sender->title(t('Dashboard')); $Sender->RequiredAdminPermissions[] = 'Garden.Settings.View'; $Sender->RequiredAdminPermissions[] = 'Garden.Settings.Manage'; $Sender->RequiredAdminPermissions[] = 'Garden.Community.Manage'; $Sender->RequiredAdminPermissions[] = 'Garden.Users.Add'; $Sender->RequiredAdminPermissions[] = 'Garden.Users.Edit'; $Sender->RequiredAdminPermissions[] = 'Garden.Users.Delete'; $Sender->RequiredAdminPermissions[] = 'Garden.Users.Approve'; $Sender->fireEvent('DefineAdminPermissions'); $Sender->permission($Sender->RequiredAdminPermissions, '', false); $Sender->addSideMenu('dashboard/settings'); if (!Gdn_Statistics::checkIsEnabled() && Gdn_Statistics::checkIsLocalhost()) { $Sender->render('dashboardlocalhost', '', 'plugins/VanillaStats'); } else { $Sender->addJsFile('vanillastats.js', 'plugins/VanillaStats'); $Sender->addJsFile('picker.js', 'plugins/VanillaStats'); $Sender->addCSSFile('picker.css', 'plugins/VanillaStats'); $this->configureRange($Sender); $VanillaID = Gdn::installationID(); $Sender->setData('VanillaID', $VanillaID); $Sender->setData('VanillaVersion', APPLICATION_VERSION); $Sender->setData('SecurityToken', $this->securityToken()); // Render the custom dashboard view $Sender->render('dashboard', '', 'plugins/VanillaStats'); } }
/** * Override the index of the dashboard's settings controller in the to render new statistics. * * @param SettingsController $sender Instance of the dashboard's settings controller. */ public function settingsController_home_create($sender) { $statsUrl = $this->AnalyticsServer; if (!stringBeginsWith($statsUrl, 'http:') && !stringBeginsWith($statsUrl, 'https:')) { $statsUrl = Gdn::request()->scheme() . "://{$statsUrl}"; } Gdn_Theme::section('DashboardHome'); $sender->setData('IsWidePage', true); // Tell the page where to find the Vanilla Analytics provider $sender->addDefinition('VanillaStatsUrl', $statsUrl); $sender->setData('VanillaStatsUrl', $statsUrl); // Load javascript & css, check permissions, and load side menu for this page. $sender->addJsFile('settings.js'); $sender->title(t('Dashboard')); $sender->RequiredAdminPermissions = ['Garden.Settings.View', 'Garden.Settings.Manage', 'Garden.Community.Manage']; $sender->fireEvent('DefineAdminPermissions'); $sender->permission($sender->RequiredAdminPermissions, '', false); $sender->setHighlightRoute('dashboard/settings'); if (!Gdn_Statistics::checkIsEnabled() && Gdn_Statistics::checkIsLocalhost()) { $sender->render('dashboardlocalhost', '', 'plugins/VanillaStats'); } else { $sender->addCssFile('picker.css', 'plugins/VanillaStats'); $sender->addCssFile('vendors/c3.min.css', 'plugins/VanillaStats'); $sender->addJsFile('vanillastats.js', 'plugins/VanillaStats'); $sender->addJsFile('picker.js', 'plugins/VanillaStats'); $sender->addJsFile('d3.min.js'); $sender->addJsFile('c3.min.js'); $sender->addDefinition('VanillaID', Gdn::installationID()); $sender->addDefinition('AuthToken', Gdn_Statistics::generateToken()); $sender->addDefinition('ExpandText', t('more')); $sender->addDefinition('CollapseText', t('less')); // Render the custom dashboard view $sender->render('dashboard', '', 'plugins/VanillaStats'); } }
#Content form .StatsDisabled input.Button { margin: 20px 0 0 0; } </style> <div class="StatsDisabled"> <strong><?php echo T("Vanilla Statistics are currently disabled"); ?> </strong> <?php if (!C('Garden.Analytics.Enabled', TRUE)) { echo $this->Form->Hidden('Allow', array('value' => 1)); echo "<p>" . T("Garden.StatisticsDisabled", "You have specifically disabled Vanilla Statistics in your configuration file.") . "</p>"; echo $this->Form->Button("Enable", array('class' => 'Button SliceSubmit')); } else { if (Gdn_Statistics::CheckIsLocalhost() && !C('Garden.Analytics.AllowLocal', FALSE)) { echo $this->Form->Hidden('AllowLocal', array('value' => 1)); echo "<p>" . T("Garden.StatisticsLocal.Explain", "This forum appears to be running in a test environment, or is otherwise reporting a private IP. By default, forums running on private IPs are not tracked.") . "</p>"; echo "<p>" . T("Garden.StatisticsLocal.Resolve", "If you're sure your forum is accessible from the internet you can force it to report statistics here:") . "</p>"; echo $this->Form->Button("Enable", array('class' => 'Button SliceSubmit')); } else { if (!$this->Data('ConfWritable')) { echo "<p>" . T("Garden.StatisticsReadonly.Explain", "Your config.php file appears to be read-only. This means that Vanilla will be unable to automatically register your forum's InstallationID and InstallationSecret.") . "</p>"; echo "<p>" . T("Garden.StatisticsReadonly.Resolve", "To solve this problem, assign file mode 777 to your conf/config.php file.") . "</p>"; } } } ?> <p></p> </div>