function tearDown() { Email::setMockMailer(null); if ($this->oldTemplates) { \Openclerk\Config::overwrite(array("emails_templates" => $this->oldTemplates)); } }
/** * Can be cached. */ static function calculateRelativePath() { if (self::$cached_relativePath === null) { // construct a relative path for this request based on the request URI, but only if it is set if (isset($_SERVER['REQUEST_URI']) && $_SERVER['REQUEST_URI'] && !defined('FORCE_NO_RELATIVE')) { $uri = $_SERVER['REQUEST_URI']; // strip out the hostname from the absolute_url $intended = substr(\Openclerk\Config::get('absolute_url'), strpos(\Openclerk\Config::get('absolute_url'), '://') + 4); $intended = substr($intended, strpos($intended, '/')); // if we're in this path, remove it // now generate ../s as necessary if (strtolower(substr($uri, 0, strlen($intended))) == strtolower($intended)) { $uri = substr($uri, strlen($intended)); } // but strip out any parameters, which might have /s in them, which will completely mess this up // (see issue #13) if (strpos($uri, "?") !== false) { $uri = substr($uri, 0, strpos($uri, "?")); } self::$cached_relativePath = str_repeat('../', substr_count($uri, '/')); } else { self::$cached_relativePath = ""; } } return self::$cached_relativePath; }
/** * Find the next job that should be executed. * By default, just selects any job instance that is in the database that isn't * already executing, hasn't already been finished, and hasn't errored out. * @return a job array (id, job_type, [user_id], [arg_id]) or {@code false} if there is none */ function findJob(Connection $db, Logger $logger) { // TODO timeout jobs // mark all repeatedly failing jobs as failing $execution_limit = Config::get("job_execution_limit", 5); $q = $db->prepare("SELECT * FROM jobs WHERE is_executed=0 AND is_executing=0 AND execution_count >= ?"); $q->execute(array($execution_limit)); if ($failed = $q->fetchAll()) { $logger->info("Found " . number_format(count($failed)) . " jobs that have executed too many times ({$execution_limit})"); foreach ($failed as $f) { $q = $db->prepare("UPDATE jobs SET is_executed=1,is_error=1 WHERE id=?"); $q->execute(array($f['id'])); $logger->info("Marked job " . $f['id'] . " as failed"); } } // find first a job that has zero execution count $q = $db->prepare("SELECT * FROM jobs WHERE " . $this->defaultFindJobQuery() . " AND execution_count=0 LIMIT 1"); $q->execute(); if ($job = $q->fetch()) { return $job; } // or, any job $q = $db->prepare("SELECT * FROM jobs WHERE " . $this->defaultFindJobQuery() . " LIMIT 1"); $q->execute(); return $q->fetch(); }
/** * Return an absolute URL for a page on the current site. * * Uses the value of {@code absolute_url} provided by {@link Config}. * If {@code absolute_url} ends in {@code /} and {@code $url} starts with {@code /}, * removes one of the extra slashes. * * @param $url the relative URL to link to */ function absolute_url($url) { $root = Config::get('absolute_url'); // trim any extra slash if (substr($root, -1) == "/" && substr($url, 0, 1) == "/") { $url = substr($url, 1); } return $root . $url; }
function getJSON($path) { $uri = Config::get('absolute_url') . $path; $raw = @file_get_contents($uri); $json = json_decode($raw, true); if (!$json) { throw new ApisTestException("'{$uri}' did not return valid JSON: '{$raw}'"); } return $json; }
public function fetchSupportedCurrencies(CurrencyFactory $factory, Logger $logger) { // we can emulate this with a normal balance call $key = Config::get('exchange_cryptsy_key'); // aka Application Key $secret = Config::get('exchange_cryptsy_secret'); // aka Application/Device ID $balances = $this->fetchBalances(array('api_key' => $key, 'api_secret' => $secret), $factory, $logger); return array_keys($balances); }
/** * Get a list of all job instances that should be run soon. * @return a list of job parameters */ function getPending(\Db\Connection $db) { $q = $db->prepare("SELECT * FROM performance_reports WHERE created_at > DATE_SUB(NOW(), INTERVAL " . \Openclerk\Config::get("job_metrics_report_interval", 60 * 12) . " MINUTE) LIMIT 1"); $q->execute(); if (!$q->fetch()) { // there's no recent reports; make another one return array(array("job_type" => $this->getName(), "arg" => null)); } return array(); }
function __construct(Exchange $exchange) { $this->logger = new Logger("test"); $this->exchange = $exchange; if ($this->isDebug()) { $this->logger->pushHandler(new BufferHandler(new ErrorLogHandler())); } else { $this->logger->pushHandler(new NullHandler()); } Config::overwrite(array("get_contents_timeout" => 10)); }
function __construct(Currency $currency) { $this->logger = new Logger("test"); $this->currency = $currency; if ($this->isDebug()) { $this->logger->pushHandler(new BufferHandler(new ErrorLogHandler())); } else { $this->logger->pushHandler(new NullHandler()); } Config::merge(array($currency->getCode() . "_confirmations" => 6, "get_contents_timeout" => 30)); }
function __construct(AccountType $account) { $this->logger = new Logger("test"); $this->factory = $this; $this->account = $account; if ($this->isDebug()) { $this->logger->pushHandler(new BufferHandler(new ErrorLogHandler())); } else { $this->logger->pushHandler(new NullHandler()); } Config::merge(array("get_contents_timeout" => 30)); }
function generatePostData($method, $req = array()) { $key = Config::get('exchange_cryptsy_key'); // aka Application Key $secret = Config::get('exchange_cryptsy_secret'); // aka Application/Device ID $req['method'] = $method; $mt = explode(' ', microtime()); $req['nonce'] = $mt[1]; // generate the POST data string $post_data = http_build_query($req, '', '&'); // generate the extra headers $headers = array('Sign: ' . hash_hmac('sha512', $post_data, $secret), 'Key: ' . $key); return array('post' => $post_data, 'headers' => $headers); }
/** * Load the {@link ProviderInterface} with the given key, from {@link #getProviders()}. * * @param $redirect the `redirectUri` to provide the provider. * @return A {@link ProviderInterface} */ static function loadProvider($key, $redirect) { if (!$redirect) { throw new \InvalidArgumentException("No redirect provided."); } switch ($key) { case "google": return new GoogleWithOpenID(array('clientId' => \Openclerk\Config::get("oauth2_google_client_id"), 'clientSecret' => \Openclerk\Config::get("oauth2_google_client_secret"), 'redirectUri' => $redirect, 'scopes' => array('email', 'openid'), 'openid.realm' => \Openclerk\Config::get('openid_host'))); case "facebook": return new \League\OAuth2\Client\Provider\Facebook(array('clientId' => \Openclerk\Config::get("oauth2_facebook_app_id"), 'clientSecret' => \Openclerk\Config::get("oauth2_facebook_app_secret"), 'redirectUri' => $redirect, 'scopes' => array('email'))); case "github": return new \League\OAuth2\Client\Provider\Github(array('clientId' => \Openclerk\Config::get("oauth2_github_client_id"), 'clientSecret' => \Openclerk\Config::get("oauth2_github_client_secret"), 'redirectUri' => $redirect, 'scopes' => array('email'))); default: throw new UserAuthenticationException("No such known OAuth2 provider '{$key}'"); } }
function openclerk_exceptions_exception_handler($e) { header('HTTP/1.0 500 Internal Server Error'); // TODO // if (function_exists('my_content_type_exception_handler')) { // my_content_type_exception_handler($e); // } else { echo "Error: " . htmlspecialchars($e->getMessage()); if (!Config::isEmpty() && Config::get('display_errors', false)) { // only display trace locally echo "<br>Trace:"; print_exception_trace($e); } // } // logging log_uncaught_exception($e); die; }
function persist(\Db\Connection $db, $use_cookies = false) { $user_key = sprintf("%04x%04x%04x%04x", rand(0, 0xffff), rand(0, 0xffff), rand(0, 0xffff), rand(0, 0xffff)); // create a new valid user key $q = $db->prepare("INSERT INTO user_valid_keys SET user_id=?, user_key=?"); $q->execute(array($this->getId(), $user_key)); $_SESSION['user_id'] = $this->getId(); $_SESSION['user_key'] = $user_key; unset($_SESSION['no_autologin']); if ($use_cookies) { $_COOKIE['autologin_id'] = $this->getId(); $_COOKIE['autologin_key'] = $user_key; } // delete old web keys $days = \Openclerk\Config::get("autologin_expire_days"); $q = $db->prepare("DELETE FROM user_valid_keys WHERE user_id=? AND created_at < DATE_SUB(NOW(), INTERVAL {$days} DAY)"); $q->execute(array($this->getId())); }
/** * @throws UserSignupException if the user could not be signed up, with a reason * @throws UserAlreadyExistsException if the user already exists in the database * @return the created {@link User} */ static function trySignup(\Db\Connection $db, OAuth2Providers $provider) { $identity = UserOAuth2::auth($provider->getProvider()); if (!$identity) { throw new UserSignupException("Could not login with OAuth2."); } $email = $identity->email; if ($email || \Openclerk\Config::get('users_require_email', false)) { if (!$email) { throw new UserSignupException("No email address found."); } if (!is_valid_email($email)) { throw new UserSignupException("That is not a valid email."); } // does a user already exist with this email? $q = $db->prepare("SELECT * FROM users WHERE email=? LIMIT 1"); $q->execute(array($email)); if ($q->fetch()) { throw new UserAlreadyExistsException("That email '" . $email . "' is already in use."); } } $uid = $identity->uid; if (!$uid) { throw new UserSignupException("No UID found"); } // does such an identity already exist? $q = $db->prepare("SELECT * FROM user_oauth2_identities WHERE provider=? AND uid=? LIMIT 1"); $q->execute(array($provider->getKey(), $uid)); if ($q->fetch()) { throw new UserAlreadyExistsException("That OAuth2 identity is already in use."); } // create a new user $q = $db->prepare("INSERT INTO users SET email=?"); $q->execute(array($email)); $user_id = $db->lastInsertId(); // create a new identity $q = $db->prepare("INSERT INTO user_oauth2_identities SET user_id=?, provider=?, uid=?"); $q->execute(array($user_id, $provider->getKey(), $uid)); return User::findUser($db, $user_id); }
function run(\Db\Connection $db, Logger $logger) { // "What pages are taking the longest to load?" // "What pages spend the most time in PHP as opposed to the database?" $report_type = "pages_slow"; // select the worst URLs $q = $db->prepare("SELECT script_name, SUM(time_taken) AS time_taken, COUNT(id) AS page_count,\n SUM(db_prepare_time) + SUM(db_execute_time) + SUM(db_fetch_time) + SUM(db_fetch_all_time) AS database_time FROM performance_metrics_pages\n GROUP BY script_name ORDER BY SUM(time_taken) / COUNT(id) LIMIT " . \Openclerk\Config::get('metrics_report_count', 20)); $q->execute(); $data = $q->fetchAll(); $q = $db->prepare("INSERT INTO performance_reports SET report_type=?"); $q->execute(array($report_type)); $report_id = $db->lastInsertId(); foreach ($data as $row) { $q = $db->prepare("INSERT INTO performance_report_slow_pages SET report_id=?, script_name=?, page_time=?, page_count=?, page_database=?"); $q->execute(array($report_id, $row['script_name'], $row['time_taken'], $row['page_count'], $row['database_time'])); } $logger->info("Created report '{$report_type}'"); // we've processed all the data we want; delete old metrics data $q = $db->prepare("DELETE FROM performance_metrics_pages"); $q->execute(); $logger->info("Deleted old metric data"); }
public function __construct(AccountType $type) { parent::__construct($type); Config::merge(array("accounts_throttle" => 1)); }
public function __construct(AccountType $type) { parent::__construct($type); Config::merge(array("accounts_throttle" => 1, "accounts_btcguild_throttle" => 15, "accounts_wemineltc_throttle" => 60)); }
public function createProvider() { return new CoinbaseProvider(array('clientId' => Config::get('coinbase_client_id'), 'clientSecret' => Config::get('coinbase_client_secret'), 'redirectUri' => Config::get('coinbase_redirect_uri'), 'scopes' => array('user', 'balance'))); }
function __construct() { Config::merge(array("get_contents_timeout" => 10)); }
function addDatabaseStats() { if (Config::get('metrics_db_enabled', true)) { return array('query' => ", db_prepares=:db_prepares, db_executes=:db_executes, db_fetches=:db_fetches, db_fetch_alls=:db_fetch_alls,\n db_prepare_time=:db_prepare_time, db_execute_time=:db_execute_time, db_fetch_time=:db_fetch_time, db_fetch_all_time=:db_fetch_all_time", 'args' => array('db_prepares' => $this->results['db_prepare_count'] * 1000, 'db_executes' => $this->results['db_execute_count'] * 1000, 'db_fetches' => $this->results['db_fetch_count'] * 1000, 'db_fetch_alls' => $this->results['db_fetch_all_count'] * 1000, 'db_prepare_time' => $this->results['db_prepare_time'] * 1000, 'db_execute_time' => $this->results['db_execute_time'] * 1000, 'db_fetch_time' => $this->results['db_fetch_time'] * 1000, 'db_fetch_all_time' => $this->results['db_fetch_all_time'] * 1000)); } else { return array('query' => '', 'args' => array()); } }
/** * Extends {@link #curl_init()} to also set {@code CURLOPT_TIMEOUT} * and {@code CURLOPT_CONNECTTIMEOUT} appropriately. * These are set based on Config::get('get_contents_timeout') and Config::get('get_contents_timeout') */ static function initCurl() { $ch = curl_init(); curl_setopt($ch, CURLOPT_TIMEOUT, Config::get('get_contents_timeout')); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, Config::get('get_contents_timeout')); return $ch; }
/** * TODO support HTML emails * @return the sent message ID * @throws MailerException if the mail could not be immediately sent */ static function phpmailer($to, $to_name, $subject, $message, $html_message = false) { $mail = new \PHPMailer(); $mail->IsSMTP(); // set mailer to use SMTP $mail->Host = \Openclerk\Config::get('phpmailer_host'); // specify main and backup server $mail->SMTPAuth = true; // turn on SMTP authentication $mail->Username = \Openclerk\Config::get('phpmailer_username'); // SMTP username $mail->Password = \Openclerk\Config::get('phpmailer_password'); // SMTP password $mail->From = \Openclerk\Config::get('phpmailer_from'); $mail->FromName = \Openclerk\Config::get('phpmailer_from_name'); $mail->Sender = \Openclerk\Config::get('phpmailer_from'); $mail->AddAddress($to, $to_name); if (\Openclerk\Config::get('phpmailer_reply_to')) { $mail->AddReplyTo(\Openclerk\Config::get('phpmailer_reply_to')); } if (\Openclerk\Config::get('phpmailer_bcc', false)) { $mail->AddBCC(\Openclerk\Config::get('phpmailer_bcc')); } $mail->Subject = $subject; if ($html_message) { $mail->Body = $html_message; $mail->AltBody = $message; $mail->IsHTML(true); } else { $mail->Body = $message; } if (!$mail->Send()) { throw new MailerException("Message could not be sent: " . $mail->ErrorInfo); } return $mail->GetLastMessageID(); }
/** * This allows all exchanges to optionally throttle multiple repeated * requests based on a runtime configuration value. * The throttle time is selected from either the * `security_exchanges_NAME_throttle` or `security_exchanges_throttle` config values, * or three seconds; * which is the time in seconds to wait between repeated requests. */ public function throttle(Logger $logger) { if (!$this->first_request) { $seconds = Config::get("security_exchanges_" . $this->getCode() . "_throttle", Config::get("security_exchanges_throttle", 3)); $logger->info("Throttling for " . $seconds . " seconds"); set_time_limit(30 + $seconds * 2); sleep($seconds); } $this->first_request = false; }
/** * @throws UserSignupException if the user could not be signed up, with a reason * @throws UserAlreadyExistsException if the identity or email already exists in the database * @return the created {@link User} */ static function trySignup(\Db\Connection $db, $email, $openid, $redirect) { if (!$redirect) { throw new \InvalidArgumentException("No redirect provided."); } if ($email || \Openclerk\Config::get('users_require_email', false)) { if (!is_valid_email($email)) { throw new UserSignupException("That is not a valid email."); } // does a user already exist with this email? $q = $db->prepare("SELECT * FROM users WHERE email=? LIMIT 1"); $q->execute(array($email)); if ($q->fetch()) { throw new UserAlreadyExistsException("That email is already in use."); } } $light = self::validateOpenID($openid, $redirect); // search for existing identities $q = $db->prepare("SELECT * FROM user_openid_identities WHERE identity=? LIMIT 1"); $q->execute(array($light->identity)); if ($identity = $q->fetch()) { throw new UserAlreadyExistsException("An account for the OpenID identity '" . $light->identity . "' already exists."); } // otherwise create a new account // create a new user $q = $db->prepare("INSERT INTO users SET email=?"); $q->execute(array($email)); $user_id = $db->lastInsertId(); // create a new identity $q = $db->prepare("INSERT INTO user_openid_identities SET user_id=?, identity=?"); $q->execute(array($user_id, $light->identity)); return User::findUser($db, $user_id); }
if (!$address) { throw new JobException("Cannot find an address " . $job['arg_id'] . " for user " . $job['user_id']); } $instance = \DiscoveredComponents\Currencies::getInstance($currency); if ($instance instanceof \Openclerk\Currencies\ConfirmableCurrency) { // directly request confirmations $balance = $instance->getBalanceWithConfirmations($address['address'], \Openclerk\Config::get($currency . "_confirmations", 6), $logger); insert_new_address_balance($job, $address, $balance); } else { if ($instance instanceof \Openclerk\Currencies\BlockBalanceableCurrency) { // get the most recent block count, to calculate confirmations $block = null; $q = db()->prepare("SELECT * FROM blockcount_" . $currency . " WHERE is_recent=1"); $q->execute(); if ($result = $q->fetch()) { $block = $result['blockcount'] - \Openclerk\Config::get($currency . "_confirmations", 6); } $balance = $instance->getBalanceAtBlock($address['address'], $block, $logger); insert_new_address_balance($job, $address, $balance); } else { // we can't do confirmations or block balances $balance = $instance->getBalance($address['address'], $logger); insert_new_address_balance($job, $address, $balance); } } if ($instance instanceof \Openclerk\Currencies\MultiBalanceableCurrency) { $balances = $instance->getMultiBalances($address['address'], $logger); foreach ($balances as $code => $balance) { if (in_array($code, get_all_currencies())) { if ($code != $currency) { // skip balances we've already inserted for this currency
function __construct() { parent::__construct(new \Exchange\Cryptsy()); // public API key details for cryptsy API \Openclerk\Config::overwrite(array("exchange_cryptsy_key" => "21222550a305da84dc", "exchange_cryptsy_secret" => "openclerk/exchanges")); }
/** * This allows all exchanges to optionally throttle multiple repeated * requests based on a runtime configuration value. * The throttle time is selected from either the * `accounts_NAME_throttle` or `accounts_throttle` config values, * or {@code $default} seconds; * which is the time in seconds to wait between repeated requests. * @param $default the default delay, or 3 seconds if not specified */ public function throttle(Logger $logger, $default = 3) { if (isset(self::$throttled[$this->getCode()])) { $seconds = Config::get("accounts_" . $this->getCode() . "_throttle", Config::get("accounts_throttle", $default)); $logger->info("Throttling for " . $seconds . " seconds"); set_time_limit(30 + $seconds * 2); sleep($seconds); } self::$throttled[$this->getCode()] = time(); }
public function getAuthorizationUrl($options = []) { return parent::getAuthorizationUrl($options) . '&openid.realm=' . (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ? "https://" : "http://") . \Openclerk\Config::get('openid_host'); }
function config($key, $default = null) { return \Openclerk\Config::get($key, $default); }