Exemplo n.º 1
0
function features_ensure_enabled($flags)
{
    if (!features_is_enabled($flags)) {
        error_disabled();
    }
    # Happy sauce!
}
Exemplo n.º 2
0
function _cache_prepare_key($key, $more = array())
{
    if (features_is_enabled("cache_prefixes")) {
        if ($prefix = $GLOBALS['cfg']['cache_prefix']) {
            $key = "{$prefix}_{$key}";
        }
    }
    return $key;
}
function api_auth_oauth2_has_auth(&$method, $key_row = null)
{
    $access_token = api_auth_oauth2_get_access_token($method);
    if (!$access_token) {
        return array('ok' => 0, 'error' => 'Required access token missing', 'error_code' => 400);
    }
    $token_row = api_oauth2_access_tokens_get_by_token($access_token);
    if (!$token_row) {
        return array('ok' => 0, 'error' => 'Invalid access token', 'error_code' => 400);
    }
    if ($token_row['disabled']) {
        return array('ok' => 0, 'error' => 'Access token is disabled', 'error_code' => 502);
    }
    if ($token_row['expires'] && $token_row['expires'] < time()) {
        return array('ok' => 0, 'error' => 'Access token has expired', 'error_code' => 400);
    }
    # I find it singularly annoying that we have to do this here
    # but OAuth gets what [redacted] wants. See also: notes in
    # lib_api.php around ln 65 (20121026/straup)
    $key_row = api_keys_get_by_id($token_row['api_key_id']);
    $rsp = api_keys_utils_is_valid_key($key_row);
    if (!$rsp['ok']) {
        return $rsp;
    }
    if (isset($method['requires_perms'])) {
        if ($token_row['perms'] < $method['requires_perms']) {
            $perms_map = api_oauth2_access_tokens_permissions_map();
            $required = $perms_map[$method['requires_perms']];
            return array('ok' => 0, 'error' => "Insufficient permissions, method requires a token with '{$required}' permissions", 'error_code' => 403);
        }
    }
    # Ensure user-iness - this may seem like a no-brainer until you think
    # about how the site itself uses the API in the absence of a logged-in
    # user (20130508/straup)
    $ensure_user = 1;
    $user = null;
    if (!$token_row['user_id'] && $key_row && features_is_enabled("api_oauth2_tokens_null_users")) {
        $key_role_id = $key_row['role_id'];
        $roles_map = api_keys_roles_map('string keys');
        $valid_roles = $GLOBALS['cfg']['api_oauth2_tokens_null_users_allowed_roles'];
        $valid_roles_ids = array();
        foreach ($valid_roles as $role) {
            $valid_roles_ids[] = $roles_map[$role];
        }
        $ensure_user = $key_role_id && in_array($key_role_id, $valid_roles_ids) ? 0 : 1;
    }
    if ($ensure_user) {
        $user = users_get_by_id($token_row['user_id']);
        if (!$user || $user['deleted']) {
            return array('ok' => 0, 'error' => 'Not a valid user', 'error_code' => 400);
        }
    }
    #
    return array('ok' => 1, 'access_token' => $token_row, 'api_key' => $key_row, 'user' => $user);
}
function api_oauth2_access_tokens_for_key(&$key, $more = array())
{
    $enc_key = AddSlashes($key['id']);
    $sql = "SELECT * FROM OAuth2AccessTokens WHERE api_key_id='{$enc_key}' AND (expires=0 OR expires > UNIX_TIMESTAMP(NOW()))";
    if (features_is_enabled(array("api_site_keys", "api_site_tokens"))) {
        # pretty sure we don't want to filter on this
        # but just in case... (20130711/straup)
        # $sql .= " AND api_key_role_id=0";
    }
    $sql .= " ORDER BY created DESC";
    $rsp = db_fetch_paginated($sql, $more);
    return $rsp;
}
Exemplo n.º 5
0
function api_keys_utils_is_valid_key($key_row)
{
    if (!$key_row) {
        return array('ok' => 0, 'error' => 'Unknown API key');
    }
    if ($key_row['deleted']) {
        return array('ok' => 0, 'error' => 'Invalid API key');
    }
    if ($key_row['disabled']) {
        return array('ok' => 0, 'error' => 'API key is disabled');
    }
    if (features_is_enabled("api_throttling") && api_throttle_is_key_throttled($key_row)) {
        return array('ok' => 0, 'error' => 'API key is throttled');
    }
    return array('ok' => 1);
}
Exemplo n.º 6
0
function api_log($data, $dispatch = 0)
{
    if (!features_is_enabled("api_logging")) {
        return;
    }
    # We could also use apache_note to store data (serialized to
    # JSON) as we go but since that's really just ... a global
    # variable it seems kind of pointless not to just do this
    # (20121026/straup)
    $GLOBALS['cfg']['api_log'] = array_merge($GLOBALS['cfg']['api_log'], $data);
    if ($dispatch) {
        $pid = getmypid();
        $note = json_encode($GLOBALS['cfg']['api_log']);
        error_log("[API][{$pid}] {$note}");
    }
}
Exemplo n.º 7
0
function api_output_send($rsp, $more = array())
{
    $rsp['stat'] = isset($more['is_error']) ? 'error' : 'ok';
    api_log(array('stat' => $rsp['stat']), 'write');
    api_output_utils_start_headers($rsp, $more);
    if (features_is_enabled("api_cors")) {
        if ($origin = $GLOBALS['cfg']['api_cors_allow_origin']) {
            header("Access-Control-Allow-Origin: " . htmlspecialchars($origin));
        }
    }
    if (!request_isset("inline")) {
        header("Content-Type: text/json");
    }
    $json = json_encode($rsp);
    header("Content-Length: " . strlen($json));
    echo $json;
    exit;
}
Exemplo n.º 8
0
function api_auth_oauth2_has_auth(&$method, $key_row = null)
{
    $access_token = api_auth_oauth2_get_access_token($method);
    if (!$access_token) {
        return array('ok' => 0, 'error' => 'Required access token missing', 'error_code' => 400);
    }
    $token_row = api_oauth2_access_tokens_get_by_token($access_token);
    if (!$token_row) {
        return array('ok' => 0, 'error' => 'Invalid access token', 'error_code' => 400);
    }
    if ($token_row['expires'] && $token_row['expires'] < time()) {
        return array('ok' => 0, 'error' => 'Access token has expired', 'error_code' => 400);
    }
    # I find it singularly annoying that we have to do this here
    # but OAuth gets what [redacted] wants. See also: notes in
    # lib_api.php around ln 65 (20121026/straup)
    $key_row = api_keys_get_by_id($token_row['api_key_id']);
    $rsp = api_keys_utils_is_valid_key($key_row);
    if (!$rsp['ok']) {
        return $rsp;
    }
    if (isset($method['requires_perms'])) {
        if ($token_row['perms'] < $method['requires_perms']) {
            return array('ok' => 0, 'error' => 'Insufficient permissions', 'error_code' => 403);
        }
    }
    # Ensure user-iness - this may seem like a no-brainer until you think
    # about how the site itself uses the API in the absence of a logged-in
    # user (20130508/straup)
    $ensure_user = 1;
    $user = null;
    if (features_is_enabled("api_site_keys", "api_site_tokens")) {
        # check that API key is a site key
        $ensure_user = $token_row['user_id'] ? 1 : 0;
    }
    if ($ensure_user) {
        $user = users_get_by_id($token_row['user_id']);
        if (!$user || $user['deleted']) {
            return array('ok' => 0, 'error' => 'Not a valid user', 'error_code' => 400);
        }
    }
    #
    return array('ok' => 1, 'access_token' => $token_row, 'api_key' => $key_row, 'user' => $user);
}
function api_output_send($rsp, $callback, $more = array())
{
    $rsp['stat'] = isset($more['is_error']) ? 'error' : 'ok';
    api_log(array('stat' => $rsp['stat']), 'write');
    api_output_utils_start_headers($rsp, $more);
    if (features_is_enabled("api_cors")) {
        if ($origin = $GLOBALS['cfg']['api_cors_allow_origin']) {
            header("Access-Control-Allow-Origin: " . htmlspecialchars($origin));
        }
    }
    $json = json_encode($rsp);
    # http://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/
    $jsonp = "/**/" . $callback . "(" . $json . ")";
    header("Content-Disposition: attachment; filename=f.txt,");
    header("X-Content-Type-Options: nosniff");
    header("Content-Length: " . strlen($jsonp));
    if (!request_isset("inline")) {
        header("Content-Type: application/javascript");
    }
    echo $jsonp;
    exit;
}
Exemplo n.º 10
0
function auth_has_role($role, $who = 0)
{
    $who = $who ? $who : $GLOBALS['cfg']['user']['id'];
    # This still needs better documentation but is here to account
    # for glue-code that Cal added for dev environments (20150613/straup)
    if (!$who && $role == "staff" && features_is_enabled("auth_roles_autopromote_staff")) {
        if ($GLOBALS['cfg']['environment'] == 'dev' && features_is_enabled("auth_roles_autopromote_staff_dev")) {
            return 1;
        }
        if ($GLOBALS['this_is_shell'] && features_is_enabled("auth_roles_autopromote_staff_shell")) {
            return 1;
        }
    }
    if (!$who) {
        return 0;
    }
    if (!isset($GLOBALS['cfg']['auth_users'][$who])) {
        return 0;
    }
    $details = $GLOBALS['cfg']['auth_users'][$who];
    $roles = $details['roles'];
    return in_array($role, $roles) ? 1 : 0;
}
<?php

$root = dirname(dirname(__FILE__));
ini_set("include_path", "{$root}/www:{$root}/www/include");
set_time_limit(0);
#
include "include/init.php";
loadlib("cli");
loadlib("flickr_backups");
loadlib("flickr_push");
loadlib("flickr_push_subscriptions");
$features = array("backups", "flickr_push", "flickr_push_backups");
if (!features_is_enabled($features)) {
    echo "backups are currently disabled\n";
    exit;
}
$spec = array("url" => array("flag" => "u", "required" => 1, "help" => "the *root* URL of your copy of parallel-ogram (the need to specify this here is not a feature...)"));
$opts = cli_getopts($spec);
$topic = $opts['topic'];
# This sucks to have to do but I am uncertain what the
# better alternative is right now... (20120601/straup)
$root = rtrim($opts['url'], '/') . "/";
$GLOBALS['cfg']['abs_root_url'] = $root;
log_info("set 'abs_root_url' to '{$GLOBALS['cfg']['abs_root_url']}'");
$topic_map = flickr_push_topic_map("string keys");
$topics = array("my_photos", "my_faves");
foreach (flickr_backups_users() as $user) {
    foreach ($topics as $topic) {
        $sub = array('user_id' => $user['id'], 'topic_id' => $topic_map[$topic]);
        $rsp = flickr_push_subscriptions_register_subscription($sub);
        log_info("[{$user['username']}] {$topic}: {$rsp['ok']}");
Exemplo n.º 12
0
<?php

# Note the order here – it's important
# (20121024/straup)
$GLOBALS['this_is_api'] = 1;
include "include/init.php";
loadlib("api");
if (features_is_enabled('ensure_post_data')) {
    api_utils_ensure_post_data();
}
$method = request_str("method");
api_dispatch($method);
exit;
Exemplo n.º 13
0
<?php

$root = dirname(dirname(__FILE__));
ini_set("include_path", "{$root}/www:{$root}/www/include");
set_time_limit(0);
#
include "include/init.php";
loadlib("flickr_backups");
if (!features_is_enabled("backups")) {
    echo "backups are currently disabled\n";
    exit;
}
foreach (flickr_backups_users() as $user) {
    log_info("backup photos for {$user['username']}");
    $rsp = flickr_backups_get_photos($user);
    dumper($rsp);
}
Exemplo n.º 14
0
function api_dispatch($method)
{
    if (!$GLOBALS['cfg']['enable_feature_api']) {
        api_output_error(999, 'API disabled');
    }
    $method = filter_strict($method);
    $api_key = request_str("api_key");
    $access_token = request_str("access_token");
    # Log the basics
    api_log(array('api_key' => $api_key, 'method' => $method, 'access_token' => $access_token, 'remote_addr' => $_SERVER['REMOTE_ADDR']));
    $methods = $GLOBALS['cfg']['api']['methods'];
    if (!$method || !isset($methods[$method])) {
        $enc_method = htmlspecialchars($method);
        api_output_error(404, "Method '{$enc_method}' not found");
    }
    apache_setenv("API_METHOD", $method);
    $method_row = $methods[$method];
    $key_row = null;
    $token_row = null;
    if (!$method_row['enabled']) {
        $enc_method = htmlspecialchars($method);
        api_output_error(404, "Method '{$enc_method}' not found");
    }
    $method_row['name'] = $method;
    if ($GLOBALS['cfg']['api_auth_type'] == 'oauth2') {
        if ($_SERVER['REQUEST_METHOD'] != 'POST' && !$GLOBALS['cfg']['api_oauth2_allow_get_parameters']) {
            api_output_error(405, 'Method not allowed');
        }
    }
    if (isset($method_row['request_method'])) {
        if ($_SERVER['REQUEST_METHOD'] != $method_row['request_method']) {
            api_output_error(405, 'Method not allowed');
        }
    }
    # Okay – now we get in to validation and authorization. Which means a
    # whole world of pedantic stupid if we're using Oauth2. Note that you
    # could use OAuth2 and require API keys be passed explictly but since
    # that's not part of the spec if you enable the two features simultaneously
    # don't be surprised when hilarity ensues. Good times. (20121026/straup)
    # First API keys
    if (features_is_enabled("api_require_keys")) {
        if (!$api_key) {
            api_output_error(999, "Required API key is missing");
        }
        $key_row = api_keys_get_by_key($api_key);
        api_keys_utils_ensure_valid_key($key_row);
    }
    # Second auth-y bits
    $auth_rsp = api_auth_ensure_auth($method_row, $key_row);
    if (isset($auth_rsp['api_key'])) {
        $key_row = $auth_rsp['api_key'];
    }
    if (isset($auth_rsp['access_token'])) {
        $token_row = $auth_rsp['access_token'];
    }
    if ($auth_rsp['user']) {
        $GLOBALS['cfg']['user'] = $auth_rsp['user'];
    }
    apache_setenv("API_KEY", $key_row['api_key']);
    # Check for require-iness of users here ?
    # Roles - for API keys (things like only the site keys)
    api_config_ensure_role($method_row, $key_row, $token_row);
    # Blessings and other method specific access controls
    api_config_ensure_blessing($method_row, $key_row, $token_row);
    # Finally, crumbs - because they are tastey
    if ($method_row['requires_crumb']) {
        api_auth_ensure_crumb($method_row);
    }
    # GO!
    loadlib($method_row['library']);
    $parts = explode(".", $method);
    $method = array_pop($parts);
    $func = "{$method_row['library']}_{$method}";
    if (!function_exists($func)) {
        api_output_error(404, "Method not found");
    }
    call_user_func($func);
    exit;
}
                error_404();
            }
        } else {
            error_404();
        }
    }
    echo get_str("challenge");
    exit;
}
# TO DO: check $subscription['topic_id'] here against
# the 'flickr_push_enable_*' flags (20111203/straup)
$xml = file_get_contents('php://input');
$atom = syndication_atom_parse_str($xml);
$user = users_get_by_id($subscription['user_id']);
$flickr_user = flickr_users_get_by_user_id($user['id']);
$do_push_backups = features_is_enabled("flickr_push_backups");
$is_push_backup = flickr_push_subscriptions_is_push_backup($subscription);
$is_backup_user = flickr_backups_is_registered_user($user, "ensure enabled");
$to_backup = array();
$new = 0;
foreach ($atom->items as $e) {
    # for debugging...
    # $fh = fopen("/tmp/wtf.json", "w");
    # fwrite($fh, json_encode($e));
    # fclose($fh);
    # TO DO: check $subscription['topic_id'] here because
    # at some point if we start to use the push stuff to
    # track things we're backing we'll need to store the
    # data in another table (20111203/straup)
    if (!preg_match("!.*/(\\d+)\$!", $e['id'], $m)) {
        continue;
function _flickr_photos_import_store($path, &$bits)
{
    $fh = fopen($path, "w");
    if (!$fh) {
        log_info("failed to create filehandle for '{$path}'");
        return 0;
    }
    fwrite($fh, $bits);
    fclose($fh);
    # The perms dance (ensuring that all files are group writable
    # is necessary if we're doing push-based backups since when a
    # push update comes through the web server needs to be able to
    # write (or update) the file. But we also need to be able to
    # write (or update) files using the backup scripts in the bin
    # directory. Good times. (20120607/straup)
    $do_perms_dance = features_is_enabled(array('flickr_push', 'flickr_push_backups'));
    if ($do_perms_dance) {
        $stat = stat($path);
        $owner = $stat['uid'];
        $whoami = getmyuid();
        if ($whoami == $owner) {
            chmod($path, 0664);
        }
    }
    return 1;
}
Exemplo n.º 17
0
function api_config_init_blessings()
{
    # $GLOBALS['timing_keys']["api_blessings"] = "API blessings";
    # $GLOBALS['timings']['api_blessings_count'] = 0;
    # $GLOBALS['timings']['api_blessings_time'] = 0;
    foreach ($GLOBALS['cfg']['api']['blessings'] as $api_key => $key_details) {
        # $GLOBALS['timings']['api_blessings_count'] += 1;
        $start = microtime_ms();
        $whoami = $api_key;
        if ($api_key == 'site_key') {
            loadlib("api_keys");
            $blessed_site_keys = features_is_enabled(array("api_site_keys", "api_site_keys_blessed")) ? 1 : 0;
            if ($blessed_site_keys && ($site_key = api_keys_fetch_site_key())) {
                $api_key = $site_key['api_key'];
            }
        }
        $blessing_defaults = array();
        foreach (array('hosts', 'tokens', 'environments') as $prop) {
            if (isset($key_details[$prop])) {
                $blessing_defaults[$prop] = $key_details[$prop];
            }
        }
        if (is_array($key_details['method_classes'])) {
            foreach ($key_details['method_classes'] as $class_spec => $blessing_details) {
                foreach ($GLOBALS['cfg']['api']['methods'] as $method_name => $method_details) {
                    if (!$method_details['requires_blessing']) {
                        continue;
                    }
                    if (!preg_match("/^{$class_spec}/", $method_name)) {
                        continue;
                    }
                    $blessing = array_merge($blessing_defaults, $blessing_details);
                    _api_config_apply_blessing($method_name, $api_key, $blessing);
                }
            }
        }
        if (is_array($key_details['methods'])) {
            foreach ($key_details['methods'] as $method_name => $blessing_details) {
                $blessing = array_merge($blessing_defaults, $blessing_details);
                _api_config_apply_blessing($method_name, $api_key, $blessing);
            }
        }
        # _api_config_apply_blessing('api.test.isBlessed', $api_key, $blessing_defaults);
        $end = microtime_ms();
        $time = $end - $start;
        # $GLOBALS['timings']['api_blessings_time'] += $time;
    }
}
Exemplo n.º 18
0
function flickr_backups_is_push_backup(&$backup, $check_subscription = 0)
{
    $push_features = array("flickr_push", "flickr_push_backups");
    if (!features_is_enabled($push_features)) {
        return 0;
    }
    $type_id = $backup['type_id'];
    $map = flickr_backups_push_topics_map();
    if (!isset($map[$type_id])) {
        return 0;
    }
    # Stub subscription data
    $user = users_get_by_id($backup['user_id']);
    $topic_id = $map[$type_id];
    $sub = array('user_id' => $user['id'], 'topic_id' => $topic_id);
    if (!flickr_backups_is_registered_push_subscription($sub)) {
        return 0;
    }
    if ($check_subscription) {
        if (!flickr_push_subscriptions_get_by_user_and_topic($user, $topic_id)) {
            return 0;
        }
    }
    return 1;
}
Exemplo n.º 19
0
function api_utils_features_ensure_enabled($f)
{
    if (!features_is_enabled($f)) {
        api_output_error(502, "This feature is disabled");
    }
}
Exemplo n.º 20
0
loadlib('http');
loadlib('paginate');
$end = microtime_ms();
$time = $end - $start;
$GLOBALS['timings']['loadlib_default_count'] = 17;
$GLOBALS['timings']['loadlib_default_time'] = $time;
$start = microtime_ms();
if (isset($GLOBALS['cfg']['autoload_libs']) && is_array($GLOBALS['cfg']['autoload_libs'])) {
    foreach ($GLOBALS['cfg']['autoload_libs'] as $lib) {
        $GLOBALS['timings']['loadlib_auto_count'] += 1;
        loadlib($lib);
    }
}
if (isset($GLOBALS['cfg']['autoload_libs_if_enabled']) && is_array($GLOBALS['cfg']['autoload_libs_if_enabled'])) {
    foreach ($GLOBALS['cfg']['autoload_libs_if_enabled'] as $feature => $libs) {
        if (features_is_enabled($feature)) {
            if (!is_array($libs)) {
                $libs = array($libs);
            }
            foreach ($libs as $lib) {
                $GLOBALS['timings']['loadlib_auto_count'] += 1;
                loadlib($lib);
            }
        }
    }
}
$end = microtime_ms();
$time = $end - $start;
$GLOBALS['timings']['loadlib_auto_time'] = $time;
if ($GLOBALS['cfg']['site_disabled'] && !$this_is_shell) {
    loadlib("http_codes");