From abc9d8f25b45a69aa8d51c94767fd12104bb5816 Mon Sep 17 00:00:00 2001 From: Chaoyi Zha Date: Sun, 12 Mar 2017 18:35:19 -0400 Subject: [PATCH] Refactor stats API and fix bounds detection --- app/Helpers/StatsHelper.php | 10 ++- app/Helpers/UserHelper.php | 5 +- .../Api/ApiAnalyticsController.php | 61 ++++++++++++++++++- .../Controllers/Api/ApiLinkController.php | 4 +- app/Http/Controllers/UserController.php | 6 -- app/Http/routes.php | 4 ++ resources/views/env.blade.php | 1 + 7 files changed, 76 insertions(+), 15 deletions(-) diff --git a/app/Helpers/StatsHelper.php b/app/Helpers/StatsHelper.php index 93d5bbc..a84e2ba 100644 --- a/app/Helpers/StatsHelper.php +++ b/app/Helpers/StatsHelper.php @@ -15,7 +15,15 @@ class StatsHelper { if (!$this->left_bound_parsed->lte($this->right_bound_parsed)) { // If left bound is not less than or equal to right bound - throw new Exception('Invalid bounds.'); + throw new \Exception('Invalid bounds.'); + } + + $days_diff = $this->left_bound_parsed->diffInDays($this->right_bound_parsed); + $max_days_diff = env('_ANALYTICS_MAX_DAYS_DIFF') ?: 365; + + if ($days_diff > $max_days_diff) { + error_log('too big fam'); + throw new \Exception('Bounds too broad.'); } } diff --git a/app/Helpers/UserHelper.php b/app/Helpers/UserHelper.php index 9b85fca..222fbaa 100644 --- a/app/Helpers/UserHelper.php +++ b/app/Helpers/UserHelper.php @@ -31,9 +31,8 @@ class UserHelper { return ctype_alnum($username); } - public static function validateEmail($email) { - // TODO validate email here - return true; + public static function userIsAdmin($username) { + return (self::getUserByUsername($username)->role == self::$USER_ROLES['admin']); } public static function checkCredentials($username, $password) { diff --git a/app/Http/Controllers/Api/ApiAnalyticsController.php b/app/Http/Controllers/Api/ApiAnalyticsController.php index 478dddd..8e4bc7e 100644 --- a/app/Http/Controllers/Api/ApiAnalyticsController.php +++ b/app/Http/Controllers/Api/ApiAnalyticsController.php @@ -2,14 +2,69 @@ namespace App\Http\Controllers\Api; use Illuminate\Http\Request; -// use App\Factories\LinkFactory; use App\Helpers\LinkHelper; +use App\Helpers\UserHelper; use App\Helpers\StatsHelper; -class ApiLinkController extends ApiController { - public function lookupLinkAnalytics (Request $request) { +class ApiAnalyticsController extends ApiController { + public function lookupLinkStats (Request $request, $stats_type=false) { $response_type = $request->input('response_type'); + + if ($response_type != 'json') { + abort(401, 'Only JSON-encoded data is available for this endpoint.'); + } + $user = self::getApiUserInfo($request); + $validator = \Validator::make($request->all(), [ + 'url_ending' => 'required|alpha_dash', + 'stats_type' => 'alpha_num', + 'left_bound' => 'date', + 'right_bound' => 'date' + ]); + + error_log($validator->errors()); + if ($validator->fails()) { + return abort(400, 'Invalid or missing parameters.'); + } + + $url_ending = $request->input('url_ending'); + $stats_type = $request->input('stats_type'); + $left_bound = $request->input('left_bound'); + $right_bound = $request->input('right_bound'); + $stats_type = $request->input('stats_type'); + + // ensure user can only read own analytics or user is admin + $link = LinkHelper::linkExists($url_ending); + + if ($link === false) { + abort(404, 'Link not found.'); + } + + if (($link->creator != $user->username) && + !(UserHelper::userIsAdmin($username))){ + // If user does not own link and is not an admin + abort(401, 'You do not have access to this link.'); + } + + $stats = new StatsHelper($link->id, $left_bound, $right_bound); + + if ($stats_type == 'day') { + $fetched_stats = $stats->getDayStats(); + } + else if ($stats_type == 'country') { + $fetched_stats = $stats->getCountryStats(); + } + else if ($stats_type == 'referer') { + $fetched_stats = $stats->getRefererStats(); + } + else { + abort(400, 'Invalid analytics type requested.'); + } + + return self::encodeResponse([ + 'url_ending' => $link->short_url, + 'data' => $fetched_stats, + ], 'data_link_' . $stats_type, $response_type, false); } } diff --git a/app/Http/Controllers/Api/ApiLinkController.php b/app/Http/Controllers/Api/ApiLinkController.php index 78ca6ac..0880df2 100644 --- a/app/Http/Controllers/Api/ApiLinkController.php +++ b/app/Http/Controllers/Api/ApiLinkController.php @@ -19,7 +19,7 @@ class ApiLinkController extends ApiController { ]); if ($validator->fails()) { - return abort(400, 'Parameters invalid or missing.'); + return abort(400, 'Invalid or missing parameters.'); } $long_url = $request->input('url'); // * required @@ -48,7 +48,7 @@ class ApiLinkController extends ApiController { ]); if ($validator->fails()) { - return abort(400, 'Parameters invalid or missing.'); + return abort(400, 'Invalid or missing parameters.'); } $url_ending = $request->input('url_ending'); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index a7df828..4899bd8 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -78,12 +78,6 @@ class UserController extends Controller { return redirect(route('signup'))->with('error', 'Sorry, your email or username already exists. Try again.'); } - $email_valid = UserHelper::validateEmail($email); - - if ($email_valid == false) { - return redirect(route('signup'))->with('error', 'Please use a valid email to sign up.'); - } - $acct_activation_needed = env('POLR_ACCT_ACTIVATION'); if ($acct_activation_needed == false) { diff --git a/app/Http/routes.php b/app/Http/routes.php index 3a6222e..bd85dce 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -68,4 +68,8 @@ $app->group(['prefix' => '/api/v2', 'namespace' => 'App\Http\Controllers'], func /* API lookup endpoints */ $app->post('action/lookup', ['as' => 'api_lookup_url', 'uses' => 'Api\ApiLinkController@lookupLink']); $app->get('action/lookup', ['as' => 'api_lookup_url', 'uses' => 'Api\ApiLinkController@lookupLink']); + + /* API data endpoints */ + $app->get('data/link', ['as' => 'api_link_analytics', 'uses' => 'Api\ApiAnalyticsController@lookupLinkStats']); + $app->post('data/link', ['as' => 'api_link_analytics', 'uses' => 'Api\ApiAnalyticsController@lookupLinkStats']); }); diff --git a/resources/views/env.blade.php b/resources/views/env.blade.php index 90d76b8..55da877 100644 --- a/resources/views/env.blade.php +++ b/resources/views/env.blade.php @@ -99,6 +99,7 @@ SESSION_DRIVER=file QUEUE_DRIVER=database _API_KEY_LENGTH=15 +_ANALYTICS_MAX_DAYS_DIFF=365 _PSEUDO_RANDOM_KEY_LENGTH=5 # FILESYSTEM_DRIVER=local