/** * set_active_instance * This sets the specified instance as the 'active' one */ public function set_active_instance($uid, $user_id = '') { // Not an admin? bubkiss! if (!$GLOBALS['user']->has_access('100')) { $user_id = $GLOBALS['user']->id; } $user_id = $user_id ? $user_id : $GLOBALS['user']->id; Preference::update('vlc_active', $user_id, intval($uid)); AmpConfig::set('vlc_active', intval($uid), true); return true; }
$media_ids[] = array('object_type' => 'broadcast', 'object_id' => scrub_in($_REQUEST['id'])); break; default: break; } // end action switch // See if we need a special streamtype switch ($_REQUEST['action']) { case 'download': $stream_type = 'download'; break; case 'democratic': // Don't let them loop it // FIXME: This looks hacky if (AmpConfig::get('play_type') == 'democratic') { AmpConfig::set('play_type', 'stream', true); } default: $stream_type = AmpConfig::get('play_type'); if ($stream_type == 'stream') { $stream_type = AmpConfig::get('playlist_type'); } break; } debug_event('stream.php', 'Stream Type: ' . $stream_type . ' Media IDs: ' . json_encode($media_ids), 5); if (count(media_ids)) { $playlist = new Stream_Playlist(); $playlist->add($media_ids); if (isset($urls)) { $playlist->add_urls($urls); }
/** * disconnect * * This nukes the dbh connection, this isn't used very often... */ public static function disconnect($database = '') { if (!$database) { $database = AmpConfig::get('database_name'); } $handle = 'dbh_' . $database; // Nuke it debug_event('Dba', 'Database disconnection.', 6); AmpConfig::set($handle, null, true); return true; }
$plex_match_email = AmpConfig::get('plex_match_email'); $plexact = $_REQUEST['plexact']; switch ($plexact) { case 'auth_myplex': $myplex_username = $_POST['myplex_username']; $myplex_password = $_POST['myplex_password']; $plex_public_port = $_POST['plex_public_port']; if (!empty($myplex_username)) { // Register the server on myPlex and get auth token $myplex_authtoken = Plex_Api::validateMyPlex($myplex_username, $myplex_password); if (!empty($myplex_authtoken)) { echo T_('myPlex authentication completed.') . "<br />\r\n"; Preference::update('myplex_username', -1, $myplex_username, true, true); Preference::update('myplex_authtoken', -1, $myplex_authtoken, true, true); Preference::update('plex_public_port', -1, $plex_public_port, true, true); AmpConfig::set('plex_public_port', $plex_public_port, true); $plex_public_address = Plex_Api::getPublicIp(); Preference::update('plex_public_address', -1, $plex_public_address, true, true); $ret = Plex_Api::registerMyPlex($myplex_authtoken); if ($ret['status'] == '201') { Plex_Api::publishDeviceConnection($myplex_authtoken); $myplex_published = true; echo T_('Server registration completed.') . "<br />\r\n"; } else { $myplex_published = false; echo "<p class='error'>" . T_('Cannot register the server on myPlex.') . "</p>"; } Preference::update('myplex_published', -1, $myplex_published, true, true); } else { $myplex_authtoken = ''; $myplex_published = false;
public static function auth_user() { $isLocal = self::is_local(); $headers = apache_request_headers(); $myplex_token = $headers['X-Plex-Token']; if (empty($myplex_token)) { $myplex_token = $_REQUEST['X-Plex-Token']; } if (!$isLocal) { $match_users = AmpConfig::get('plex_match_email'); $myplex_username = $headers['X-Plex-Username']; if (empty($myplex_token)) { // Never fail OPTIONS requests if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { self::setPlexHeader($headers); exit; } else { debug_event('Access Control', 'Authentication token is missing.', '3'); self::createError(401); } } $createSession = false; Session::gc(); $username = ""; $email = trim(Session::read((string) $myplex_token)); if (empty($email)) { $createSession = true; $xml = self::get_server_authtokens(); $validToken = false; foreach ($xml->access_token as $tk) { if ((string) $tk['token'] == $myplex_token) { $username = (string) $tk['username']; // We should apply filter and access restriction to shared sections only, but that's not easily possible with current Ampache architecture $validToken = true; break; } } if (!$validToken) { debug_event('Access Control', 'Auth-Token ' . $myplex_token . ' invalid for this server.', '3'); self::createError(401); } } // Need to get a match between Plex and Ampache users if ($match_users) { if (!AmpConfig::get('access_control')) { debug_event('Access Control', 'Error Attempted to use Plex with Access Control turned off and plex/ampache link enabled.', '3'); self::createError(401); } if (empty($email)) { $xml = self::get_users_account(); if ((string) $xml->username == $username) { $email = (string) $xml->email; } else { $xml = self::get_server_friends(); foreach ($xml->User as $xuser) { if ((string) $xuser['username'] == $username) { $email = (string) $xuser['email']; } } } } if (!empty($email)) { $user = User::get_from_email($email); } if (!isset($user) || !$user->id) { debug_event('Access Denied', 'Unable to get an Ampache user match for email ' . $email, '3'); self::createError(401); } else { $username = $user->username; if (!Access::check_network('init-api', $username, 5)) { debug_event('Access Denied', 'Unauthorized access attempt to Plex [' . $_SERVER['REMOTE_ADDR'] . ']', '3'); self::createError(401); } else { $GLOBALS['user'] = $user; $GLOBALS['user']->load_playlist(); } } } else { $email = $username; $username = null; $GLOBALS['user'] = new User(); $GLOBALS['user']->load_playlist(); } if ($createSession) { // Create an Ampache session from Plex authtoken Session::create(array('type' => 'api', 'sid' => $myplex_token, 'username' => $username, 'value' => $email)); } } else { AmpConfig::set('cookie_path', '/', true); $sid = $_COOKIE[AmpConfig::get('session_name')]; if (!$sid) { $sid = $myplex_token; if ($sid) { session_id($sid); Session::create_cookie(); } } if (!empty($sid) && Session::exists('api', $sid)) { Session::check(); $GLOBALS['user'] = User::get_from_username($_SESSION['userdata']['username']); } else { $GLOBALS['user'] = new User(); $data = array('type' => 'api', 'sid' => $sid); Session::create($data); Session::check(); } $GLOBALS['user']->load_playlist(); } }
if (floatval(phpversion()) < 5) { echo "ERROR: Ampache requires PHP5"; exit; } error_reporting(E_ERROR); // Only show fatal errors in production $load_time_begin = microtime(true); $ampache_path = dirname(__FILE__); $prefix = realpath($ampache_path . "/../"); $configfile = $prefix . '/config/ampache.cfg.php'; require_once $prefix . '/lib/general.lib.php'; require_once $prefix . '/lib/class/ampconfig.class.php'; require_once $prefix . '/lib/class/core.class.php'; require_once $prefix . '/modules/php-gettext/gettext.inc'; // Define some base level config options AmpConfig::set('prefix', $prefix); // Register the autoloader spl_autoload_register(array('Core', 'autoload'), true, true); require_once $prefix . '/modules/requests/Requests.php'; Requests::register_autoloader(); // Check to see if this is http or https if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') { $http_type = 'https://'; } else { $http_type = 'http://'; } if (isset($_SERVER['HTTP_X_FORWARDED_PORT'])) { $http_port = $_SERVER['HTTP_X_FORWARDED_PORT']; } else { if (isset($_SERVER['SERVER_PORT'])) { $http_port = $_SERVER['SERVER_PORT'];
/** * Get latest available version from GitHub. * @param boolean $force * @return string */ public static function get_latest_version($force = false) { $lastversion = ''; // Forced or last check expired, check latest version from Github if ($force || self::lastcheck_expired() && AmpConfig::get('autoupdate')) { // Always update last check time to avoid infinite check on permanent errors (proxy, firewall, ...) $time = time(); Preference::update('autoupdate_lastcheck', $GLOBALS['user']->id, $time); AmpConfig::set('autoupdate_lastcheck', $time, true); // Development version, get latest commit on develop branch if (self::is_develop()) { $commits = self::github_request('/commits/develop'); if (!empty($commits)) { $lastversion = $commits->sha; Preference::update('autoupdate_lastversion', $GLOBALS['user']->id, $lastversion); AmpConfig::set('autoupdate_lastversion', $lastversion, true); $available = self::is_update_available(true); Preference::update('autoupdate_lastversion_new', $GLOBALS['user']->id, $available); AmpConfig::set('autoupdate_lastversion_new', $available, true); } } else { $tags = self::github_request('/tags'); if (!empty($tags)) { $lastversion = $tags[0]->name; Preference::update('autoupdate_lastversion', $GLOBALS['user']->id, $lastversion); AmpConfig::set('autoupdate_lastversion', $lastversion, true); $available = self::is_update_available(true); Preference::update('autoupdate_lastversion_new', $GLOBALS['user']->id, $available); AmpConfig::set('autoupdate_lastversion_new', $available, true); } } } else { $lastversion = AmpConfig::get('autoupdate_lastversion'); } return $lastversion; }
$GLOBALS['user'] = new User($_SESSION['userdata']['uid']); } else { $GLOBALS['user'] = new User(); } } // If NO_SESSION passed // Load the Preferences from the database Preference::init(); if (session_id()) { Session::extend(session_id()); // We only need to create the tmp playlist if we have a session $GLOBALS['user']->load_playlist(); } /* Add in some variables for ajax done here because we need the user */ AmpConfig::set('ajax_url', AmpConfig::get('web_path') . '/server/ajax.server.php', true); AmpConfig::set('ajax_server', AmpConfig::get('web_path') . '/server', true); // Load gettext mojo load_gettext(); /* Set CHARSET */ header("Content-Type: text/html; charset=" . AmpConfig::get('site_charset')); /* Clean up a bit */ unset($array); unset($results); /* Check to see if we need to perform an update */ if (!defined('OUTDATED_DATABASE_OK')) { if (Update::need_update()) { header("Location: " . AmpConfig::get('web_path') . "/update.php"); exit; } } // For the XMLRPC stuff
if (!$htmllang) { if ($_ENV['LANG']) { $lang = $_ENV['LANG']; } else { $lang = 'en_US'; } if (strpos($lang, '.')) { $langtmp = explode('.', $lang); $htmllang = $langtmp[0]; $charset = $langtmp[1]; } else { $htmllang = $lang; } } AmpConfig::set('lang', $htmllang, true); AmpConfig::set('site_charset', $charset ?: 'UTF-8', true); load_gettext(); header('Content-Type: text/html; charset=' . AmpConfig::get('site_charset')); // Correct potential \ or / in the dirname $safe_dirname = rtrim(dirname($_SERVER['PHP_SELF']), "/\\"); $web_path = $http_type . $_SERVER['HTTP_HOST'] . $safe_dirname; unset($safe_dirname); switch ($_REQUEST['action']) { case 'create_db': $new_user = ''; $new_pass = ''; if ($_POST['db_user'] == 'create_db_user') { $new_user = $_POST['db_username']; $new_pass = $_POST['db_password']; if (!strlen($new_user) || !strlen($new_pass)) { Error::add('general', T_('Error: Ampache SQL Username or Password missing'));
$new = $_POST['type']; break; case 'web_player': $new = $_POST['type']; // Rien a faire break; default: $new = 'stream'; $results['rfc3514'] = '0x1'; break 2; } // end switch $current = AmpConfig::get('play_type'); // Go ahead and update their preference if (Preference::update('play_type', $GLOBALS['user']->id, $new)) { AmpConfig::set('play_type', $new, true); } if ($new == 'localplay' and $current != 'localplay' or $current == 'localplay' and $new != 'localplay') { $results['rightbar'] = UI::ajax_include('rightbar.inc.php'); } $results['rfc3514'] = '0x0'; break; case 'directplay': debug_event('stream.ajax.php', 'Play type {' . $_REQUEST['playtype'] . '}', 5); $object_type = $_REQUEST['object_type']; $object_id = $_REQUEST['object_id']; if (is_array($object_id)) { $object_id = implode(',', $object_id); } if (Core::is_playable_item($object_type)) { $_SESSION['iframe']['target'] = AmpConfig::get('web_path') . '/stream.php?action=play_item&object_type=' . $object_type . '&object_id=' . $object_id;
public function generate_playlist($type, $redirect = false) { if (!count($this->urls)) { debug_event('stream_playlist', 'Error: Empty URL array for ' . $this->id, 2); return false; } debug_event('stream_playlist', 'Generating a {' . $type . '} object...', 5); $ext = $type; switch ($type) { case 'download': case 'democratic': case 'localplay': case 'web_player': // These are valid, but witchy $ct = ""; $redirect = false; unset($ext); break; case 'asx': $ct = 'video/x-ms-wmv'; break; case 'pls': $ct = 'audio/x-scpls'; break; case 'ram': $ct = 'audio/x-pn-realaudio ram'; break; case 'simple_m3u': $ext = 'm3u'; $ct = 'audio/x-mpegurl'; break; case 'xspf': $ct = 'application/xspf+xml'; break; case 'm3u': default: // Assume M3U if the pooch is screwed $ext = $type = 'm3u'; $ct = 'audio/x-mpegurl'; break; } if ($redirect) { // Our ID is the SID, so we always want to include it AmpConfig::set('require_session', true, true); header('Location: ' . Stream::get_base_url() . 'uid=' . scrub_out($this->user) . '&type=playlist&playlist_type=' . scrub_out($type)); exit; } if (isset($ext)) { header('Cache-control: public'); header('Content-Disposition: filename=ampache_playlist.' . $ext); header('Content-Type: ' . $ct . ';'); } $this->{'create_' . $type}(); }
exit; } // If the session exists then let's try to pull some data from it to see if we're still allowed to do this $username = $_REQUEST['action'] == 'handshake' || $_REQUEST['action'] == 'ping' ? $_REQUEST['user'] : Session::username($_REQUEST['auth']); if (!Access::check_network('init-api', $username, 5)) { debug_event('Access Denied', 'Unauthorized access attempt to API [' . $_SERVER['REMOTE_ADDR'] . ']', '3'); ob_end_clean(); echo XML_Data::error('403', T_('Unauthorized access attempt to API - ACL Error')); exit; } if ($_REQUEST['action'] != 'handshake' and $_REQUEST['action'] != 'ping') { Session::extend($_REQUEST['auth']); $GLOBALS['user'] = User::get_from_username($username); } // Make sure beautiful url is disabled as it is not supported by most Ampache clients AmpConfig::set('stream_beautiful_url', false, true); // Get the list of possible methods for the Ampache API $methods = get_class_methods('api'); // Define list of internal functions that should be skipped $internal_functions = array('set_filter'); // Recurse through them and see if we're calling one of them foreach ($methods as $method) { if (in_array($method, $internal_functions)) { continue; } // If the method is the same as the action being called // Then let's call this function! if ($_GET['action'] == $method) { call_user_func(array('api', $method), $_GET); // We only allow a single function to be called, and we assume it's cleaned up! exit;
* to layout this page. */ if (isset($is_header) && $is_header) { $is_header = false; } else { $is_header = true; } // Pull these variables out to allow shorthand (easier for lazy programmers) $limit = $browse->get_offset(); $start = $browse->get_start(); $total = $browse->get_total(); if (isset($_REQUEST['browse_uid'])) { $uid = $_REQUEST['browse_uid']++; } else { $uid = AmpConfig::get('list_header_uid'); AmpConfig::set('list_header_uid', ++$uid, true); } $sides = 0; if (!$browse->get_use_pages() && !$is_header) { $this->show_next_link(); ?> </p> </div> <script type="text/javascript"> $('#browse_<?php echo $browse->id; ?> _scroll').jscroll({ autoTrigger: true, nextSelector: 'a.jscroll-next:last', autoTriggerUntil: 5,
/** * create_remember_cookie * * This function just creates the remember me cookie, nothing special. */ public static function create_remember_cookie() { $remember_length = AmpConfig::get('remember_length'); $session_name = AmpConfig::get('session_name'); AmpConfig::set('cookie_life', $remember_length, true); setcookie($session_name . '_remember', "Rappelez-vous, rappelez-vous le 27 mars", time() + $remember_length, '/'); }
/** * disconnect * * This nukes the dbh connection, this isn't used very often... */ public static function disconnect($database = '') { if (!$database) { $database = AmpConfig::get('database_name'); } $handle = 'dbh_' . $database; // Nuke it AmpConfig::set($handle, null, true); return true; }