Пример #1
0
 /**
  * Retrieve the full size URL for a submission
  *
  * @param string $id
  * @param string $prov
  *
  * @return null|string
  */
 static function getFullsizeURL($id, $prov)
 {
     $stash_url = $prov === 'sta.sh' ? "http://sta.sh/{$id}" : "http://fav.me/{$id}";
     try {
         $stashpage = HTTP::legitimateRequest($stash_url, null, null);
     } catch (CURLRequestException $e) {
         if ($e->getCode() === 404) {
             return 404;
         }
         return 1;
     } catch (\Exception $e) {
         return 2;
     }
     if (empty($stashpage)) {
         return 3;
     }
     $STASH_DL_LINK_REGEX = '(https?://(sta\\.sh|www\\.deviantart\\.com)/download/\\d+/[a-z\\d_]+-d[a-z\\d]{6,}\\.(?:png|jpe?g|bmp)\\?[^"]+)';
     $urlmatch = preg_match(new RegExp('<a\\s+class="[^"]*?dev-page-download[^"]*?"\\s+href="' . $STASH_DL_LINK_REGEX . '"'), $stashpage['response'], $_match);
     if (!$urlmatch) {
         return 4;
     }
     $fullsize_url = HTTP::findRedirectTarget(htmlspecialchars_decode($_match[1]), $stash_url);
     if (empty($fullsize_url)) {
         return 5;
     }
     global $Database;
     if ($Database->where('id', $id)->where('provider', $prov)->has('deviation_cache')) {
         $Database->where('id', $id)->where('provider', $prov)->update('deviation_cache', array('fullsize' => $fullsize_url));
     }
     return URL::makeHttps($fullsize_url);
 }
Пример #2
0
 /**
  * Checks if a user is a club member
  * (currently only works for recently added members, does not deal with old members or admins)
  *
  * @return bool
  */
 function isClubMember()
 {
     $RecentlyJoined = HTTP::legitimateRequest('http://mlp-vectorclub.deviantart.com/modals/memberlist/');
     return !empty($RecentlyJoined['response']) && preg_match(new RegExp('<a class="[a-z ]*username" href="http://' . strtolower($this->name) . '.deviantart.com/">' . USERNAME_PATTERN . '</a>'), $RecentlyJoined['response']);
 }
Пример #3
0
 /**
  * Requests or refreshes an Access Token
  * $type defaults to 'authorization_code'
  *
  * @param string $code
  * @param null|string $type
  *
  * @return User|void
  */
 static function getToken(string $code, string $type = null)
 {
     global $Database, $http_response_header;
     if (empty($type) || !in_array($type, array('authorization_code', 'refresh_token'))) {
         $type = 'authorization_code';
     }
     $URL_Start = 'https://www.deviantart.com/oauth2/token?client_id=' . DA_CLIENT . '&client_secret=' . DA_SECRET . "&grant_type={$type}";
     switch ($type) {
         case "authorization_code":
             $json = DeviantArt::request("{$URL_Start}&code={$code}" . OAUTH_REDIRECT_URI, false);
             break;
         case "refresh_token":
             $json = DeviantArt::request("{$URL_Start}&refresh_token={$code}", false);
             break;
     }
     if (empty($json)) {
         if (Cookie::exists('access')) {
             $Database->where('access', Cookie::get('access'))->delete('sessions');
             Cookie::delete('access', Cookie::HTTPONLY);
         }
         HTTP::redirect("/da-auth?error=server_error&error_description={$http_response_header[0]}");
     }
     if (empty($json['status'])) {
         HTTP::redirect("/da-auth?error={$json['error']}&error_description={$json['error_description']}");
     }
     $userdata = DeviantArt::request('user/whoami', $json['access_token']);
     /** @var $User Models\User */
     $User = $Database->where('id', $userdata['userid'])->getOne('users');
     if (isset($User->role) && $User->role === 'ban') {
         $_GET['error'] = 'user_banned';
         $BanReason = $Database->where('target', $User->id)->orderBy('entryid', 'ASC')->getOne('log__banish');
         if (!empty($BanReason)) {
             $_GET['error_description'] = $BanReason['reason'];
         }
         return;
     }
     $UserID = strtolower($userdata['userid']);
     $UserData = array('name' => $userdata['username'], 'avatar_url' => URL::makeHttps($userdata['usericon']));
     $AuthData = array('access' => $json['access_token'], 'refresh' => $json['refresh_token'], 'expires' => date('c', time() + intval($json['expires_in'])), 'scope' => $json['scope']);
     $cookie = bin2hex(random_bytes(64));
     $AuthData['token'] = sha1($cookie);
     $browser = CoreUtils::detectBrowser();
     foreach ($browser as $k => $v) {
         if (!empty($v)) {
             $AuthData[$k] = $v;
         }
     }
     if (empty($User)) {
         $MoreInfo = array('id' => $UserID, 'role' => 'user');
         $makeDev = !$Database->has('users');
         if ($makeDev) {
             $MoreInfo['id'] = strtoupper($MoreInfo['id']);
         }
         $Insert = array_merge($UserData, $MoreInfo);
         $Database->insert('users', $Insert);
         $User = new User($Insert);
         if ($makeDev) {
             $User->updateRole('developer');
         }
     } else {
         $Database->where('id', $UserID)->update('users', $UserData);
     }
     if (empty($makeDev) && !empty($User) && Permission::insufficient('member', $User->role) && $User->isClubMember()) {
         $User->updateRole('member');
     }
     if ($type === 'refresh_token') {
         $Database->where('refresh', $code)->update('sessions', $AuthData);
     } else {
         $Database->where('user', $User->id)->where('scope', $AuthData['scope'], '!=')->delete('sessions');
         $Database->insert('sessions', array_merge($AuthData, array('user' => $UserID)));
     }
     $Database->rawQuery("DELETE FROM sessions WHERE \"user\" = ? && lastvisit <= NOW() - INTERVAL '1 MONTH'", array($UserID));
     Cookie::set('access', $cookie, time() + Time::$IN_SECONDS['year'], Cookie::HTTPONLY);
     return $User ?? null;
 }
Пример #4
0
                echo "pong";
                break;
            default:
                CoreUtils::notFound();
        }
        exit;
    }
    CoreUtils::notFound();
}
// Static redirects
switch ($do) {
    // PAGES
    case "logs":
        $do = 'admin';
        $data = rtrim("logs/{$data}", '/');
        HTTP::redirect(rtrim("/{$do}/{$data}", '/'));
        break;
    case "u":
        $do = 'user';
        break;
    case "cg":
    case "colourguides":
    case "colourguide":
    case "colorguides":
        $do = 'colorguide';
        break;
}
// Load controller
$controller = INCPATH . "controllers/{$do}.php";
if (!($do === 'colorguide' && preg_match(new RegExp('\\.(svg|png)$'), $data))) {
    Users::authenticate();
Пример #5
0
 /**
  * Check authentication cookie and set global
  */
 static function authenticate()
 {
     global $Database, $signedIn, $currentUser, $Color, $color;
     CSRFProtection::detect();
     if (!POST_REQUEST && isset($_GET['CSRF_TOKEN'])) {
         HTTP::redirect(CSRFProtection::removeParamFromURL($_SERVER['REQUEST_URI']));
     }
     if (!Cookie::exists('access')) {
         return;
     }
     $authKey = Cookie::get('access');
     if (!empty($authKey)) {
         if (!preg_match(new RegExp('^[a-f\\d]+$', 'iu'), $authKey)) {
             $oldAuthKey = $authKey;
             $authKey = bin2hex($authKey);
             $Database->where('token', sha1($oldAuthKey))->update('sessions', array('token' => sha1($authKey)));
             Cookie::set('access', $authKey, time() + Time::$IN_SECONDS['year'], Cookie::HTTPONLY);
         }
         $currentUser = Users::get(sha1($authKey), 'token');
     }
     if (!empty($currentUser)) {
         if ($currentUser->role === 'ban') {
             $Database->where('id', $currentUser->id)->delete('sessions');
         } else {
             if (strtotime($currentUser->Session['expires']) < time()) {
                 $tokenvalid = false;
                 try {
                     DeviantArt::getToken($currentUser->Session['refresh'], 'refresh_token');
                     $tokenvalid = true;
                 } catch (CURLRequestException $e) {
                     $Database->where('id', $currentUser->Session['id'])->delete('sessions');
                     trigger_error("Session refresh failed for {$currentUser->name} ({$currentUser->id}) | {$e->getMessage()} (HTTP {$e->getCode()})", E_USER_WARNING);
                 }
             } else {
                 $tokenvalid = true;
             }
             if ($tokenvalid) {
                 $signedIn = true;
                 if (time() - strtotime($currentUser->Session['lastvisit']) > Time::$IN_SECONDS['minute']) {
                     $lastVisitTS = date('c');
                     if ($Database->where('id', $currentUser->Session['id'])->update('sessions', array('lastvisit' => $lastVisitTS))) {
                         $currentUser->Session['lastvisit'] = $lastVisitTS;
                     }
                 }
                 $_PrefersColour = array('Pirill-Poveniy' => true, 'itv-canterlot' => true);
                 if (isset($_PrefersColour[$currentUser->name])) {
                     $Color = 'Colour';
                     $color = 'colour';
                 }
             }
         }
     } else {
         Cookie::delete('access', Cookie::HTTPONLY);
     }
 }
Пример #6
0
 /**
  * Loads the episode page
  *
  * @param null|int|Episode $force              If null: Parses $data and loads approperiate epaisode
  *                                             If array: Uses specified arra as Episode data
  * @param bool             $serverSideRedirect Handle redirection to the correct page on the server/client side
  */
 static function loadPage($force = null, $serverSideRedirect = true)
 {
     global $data, $CurrentEpisode, $Database, $PrevEpisode, $NextEpisode, $LinkedPost;
     if ($force instanceof Episode) {
         $CurrentEpisode = $force;
     } else {
         $EpData = self::parseID($data);
         if ($EpData['season'] === 0) {
             error_log("Attempted visit to {$data} from " . (!empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '[unknown referrer]') . ', redirecting to /movie page');
             HTTP::redirect('/movie/' . $EpData['episode']);
         }
         $CurrentEpisode = empty($EpData) ? self::getLatest() : self::getActual($EpData['season'], $EpData['episode']);
     }
     if (empty($CurrentEpisode)) {
         CoreUtils::notFound();
     }
     $url = $CurrentEpisode->formatURL();
     if (!empty($LinkedPost)) {
         $url .= '#' . $LinkedPost->getID();
     }
     if ($serverSideRedirect) {
         CoreUtils::fixPath($url);
     }
     $js = array('imagesloaded.pkgd', 'jquery.ba-throttle-debounce', 'jquery.fluidbox', 'Chart', 'episode');
     if (Permission::sufficient('member')) {
         $js[] = 'episode-manage';
     }
     if (Permission::sufficient('staff')) {
         $js[] = 'moment-timezone';
         $js[] = 'episodes-manage';
     }
     if (!$CurrentEpisode->isMovie) {
         $PrevEpisode = $Database->where('no', $CurrentEpisode->no, '<')->where('season', 0, '!=')->orderBy('no', 'DESC')->getOne('episodes', 'season,episode,title,twoparter');
         $NextEpisode = $Database->where('no', $CurrentEpisode->no, '>')->where('season', 0, '!=')->orderBy('no', 'ASC')->getOne('episodes', 'season,episode,title,twoparter');
     } else {
         $PrevEpisode = $Database->where('season', 0)->where('episode', $CurrentEpisode->episode, '<')->orderBy('episode', 'DESC')->getOne('episodes', 'season,episode,title');
         $NextEpisode = $Database->where('season', 0)->where('episode', $CurrentEpisode->episode, '>')->orderBy('episode', 'ASC')->getOne('episodes', 'season,episode,title');
     }
     $heading = $CurrentEpisode->formatTitle();
     CoreUtils::loadPage(array('title' => "{$heading} - Vector Requests & Reservations", 'heading' => $heading, 'view' => 'episode', 'css' => 'episode', 'js' => $js, 'url' => $serverSideRedirect ? null : $url));
 }
Пример #7
0
            $exists = 'exists on DeviantArt';
            if (isset($un)) {
                $exists = "<a href='http://{$un}.deviantart.com/'>{$exists}</a>";
            }
            $SubMSG = "If this user {$exists}, sign in to import their details.";
        }
    }
    $canEdit = $sameUser = false;
} else {
    $sameUser = $signedIn && $User->id === $currentUser->id;
    $canEdit = !$sameUser && Permission::sufficient('staff') && Permission::sufficient($User->role);
    $pagePath = "/@{$User->name}";
    CoreUtils::fixPath($pagePath);
}
if (isset($MSG)) {
    HTTP::statusCode(404);
} else {
    if ($sameUser) {
        $CurrentSession = $currentUser->Session;
        $Database->where('id != ?', array($CurrentSession['id']));
    }
    $Sessions = $Database->where('user', $User->id)->orderBy('lastvisit', 'DESC')->get('sessions', null, 'id,created,lastvisit,platform,browser_name,browser_ver,user_agent,scope');
}
$settings = array('title' => !isset($MSG) ? ($sameUser ? 'Your' : CoreUtils::posess($User->name)) . ' ' . ($sameUser || $canEdit ? 'account' : 'profile') : 'Account', 'no-robots', 'do-css', 'js' => array('user'));
if ($canEdit) {
    $settings['js'][] = 'user-manage';
}
$showSuggestions = $User->getPendingReservationCount() < 4;
if ($showSuggestions) {
    $settings['js'][] = 'user-suggestion';
    $settings['css'][] = 'user-suggestion';
Пример #8
0
<?php

use App\HTTP;
/** @var $data string */
if (is_numeric($data)) {
    HTTP::redirect("/movie/{$data}");
} else {
    HTTP::redirect("/movie/equestria-girls-{$data}");
}
Пример #9
0
<?php

use App\CoreUtils;
use App\Episodes;
use App\HTTP;
use App\RegExp;
if (POST_REQUEST) {
    HTTP::statusCode(400, AND_DIE);
}
/** @var $data string */
if (!preg_match(new RegExp('^(req|res)/(\\d+)$'), $data, $match)) {
    CoreUtils::notFound();
}
$match[1] .= array('req' => 'uest', 'res' => 'ervation')[$match[1]];
/** @var $LinkedPost \App\Models\Post */
$LinkedPost = $Database->where('id', $match[2])->getOne("{$match[1]}s");
if (empty($LinkedPost)) {
    CoreUtils::notFound();
}
$Episode = Episodes::getActual($LinkedPost->season, $LinkedPost->episode);
if (empty($Episode)) {
    CoreUtils::notFound();
}
$Episode->LinkedPost = $LinkedPost;
Episodes::loadPage($Episode, false);
Пример #10
0
        $errdesc = $_GET['error_description'];
    }
    global $signedIn;
    if ($signedIn) {
        HTTP::redirect($_GET['state']);
    }
    Episodes::loadPage();
}
$currentUser = DeviantArt::getToken($_GET['code']);
$signedIn = !empty($currentUser);
if (isset($_GET['error'])) {
    $err = $_GET['error'];
    if (isset($_GET['error_description'])) {
        $errdesc = $_GET['error_description'];
    }
    if ($err === 'user_banned') {
        $errdesc .= "\n\nIf you'd like to appeal your ban, please <a href='http://mlp-vectorclub.deviantart.com/notes/'>send the group a note</a>.";
    }
    Episodes::loadPage();
}
if (preg_match(new RegExp('^[a-z\\d]+$', 'i'), $_GET['state'], $_match)) {
    $confirm = str_replace('{{CODE}}', $_match[0], file_get_contents(INCPATH . 'views/loginConfrim.html'));
    $confirm = str_replace('{{USERID}}', Permission::sufficient('developer') || UserPrefs::get('p_disable_ga') ? '' : $currentUser->id, $confirm);
    die($confirm);
} else {
    if (preg_match($REWRITE_REGEX, $_GET['state'])) {
        HTTP::redirect($_GET['state']);
    }
}
HTTP::redirect('/');
Пример #11
0
                    Statistics::processUsageData($RequestData, $Dataset);
                    $Data['datasets'][] = $Dataset;
                }
                $ReservationData = $Database->rawQuery(str_replace('table_name', 'reservations', $query));
                if (!empty($ReservationData)) {
                    $Dataset = array('label' => 'Reservations', 'clrkey' => 1);
                    Statistics::processUsageData($ReservationData, $Dataset);
                    $Data['datasets'][] = $Dataset;
                }
                break;
            case 'approvals':
                $Labels = $Database->rawQuery("SELECT to_char(timestamp,'{$LabelFormat}') AS key\n\t\t\t\t\tFROM log\n\t\t\t\t\tWHERE timestamp > NOW() - INTERVAL '2 MONTHS' AND reftype = 'post_lock'\n\t\t\t\t\tGROUP BY key\n\t\t\t\t\tORDER BY MIN(timestamp)");
                Statistics::processLabels($Labels, $Data);
                $Approvals = $Database->rawQuery("SELECT\n\t\t\t\t\t\tto_char(MIN(timestamp),'{$LabelFormat}') AS key,\n\t\t\t\t\t\tCOUNT(*)::INT AS cnt\n\t\t\t\t\tFROM log\n\t\t\t\t\tWHERE timestamp > NOW() - INTERVAL '2 MONTHS' AND reftype = 'post_lock'\n\t\t\t\t\tGROUP BY to_char(timestamp,'{$LabelFormat}')\n\t\t\t\t\tORDER BY MIN(timestamp)");
                if (!empty($Approvals)) {
                    $Dataset = array('label' => 'Approved posts');
                    Statistics::processUsageData($Approvals, $Dataset);
                    $Data['datasets'][] = $Dataset;
                }
                break;
        }
        Statistics::postprocessTimedData($Data);
        CoreUtils::createUploadFolder($CachePath);
        file_put_contents($CachePath, JSON::encode($Data));
        Response::done(array('data' => $Data));
    }
    CoreUtils::notFound();
}
HTTP::pushResource('/about/stats-posts');
HTTP::pushResource('/about/stats-approvals');
CoreUtils::loadPage(array('title' => 'About', 'do-css', 'js' => array('Chart', $do)));