Beispiel #1
0
 function tearDown()
 {
     Email::setMockMailer(null);
     if ($this->oldTemplates) {
         \Openclerk\Config::overwrite(array("emails_templates" => $this->oldTemplates));
     }
 }
Beispiel #2
0
 /**
  * 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;
 }
Beispiel #3
0
 /**
  * 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();
 }
Beispiel #4
0
/**
 * 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;
}
Beispiel #5
0
 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;
 }
Beispiel #6
0
 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);
 }
Beispiel #7
0
 /**
  * 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));
 }
Beispiel #11
0
 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);
 }
Beispiel #12
0
 /**
  * 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}'");
     }
 }
Beispiel #13
0
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;
}
Beispiel #14
0
 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()));
 }
Beispiel #15
0
 /**
  * @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);
 }
Beispiel #16
0
 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));
 }
Beispiel #19
0
 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')));
 }
Beispiel #20
0
 function __construct()
 {
     Config::merge(array("get_contents_timeout" => 10));
 }
Beispiel #21
0
 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());
     }
 }
Beispiel #22
0
 /**
  * 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;
 }
Beispiel #23
0
 /**
  * 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;
 }
Beispiel #25
0
 /**
  * @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);
 }
Beispiel #26
0
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
Beispiel #27
0
 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();
 }
Beispiel #29
0
 public function getAuthorizationUrl($options = [])
 {
     return parent::getAuthorizationUrl($options) . '&openid.realm=' . (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ? "https://" : "http://") . \Openclerk\Config::get('openid_host');
 }
Beispiel #30
0
function config($key, $default = null)
{
    return \Openclerk\Config::get($key, $default);
}