Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added API for getting user links #97

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions config.sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@
GoController::$templateVersion = UNL\Templates\Templates::VERSION_5_3;
}

// Defines the Hosts that can use the API and keys associated with them
// Referer Host Name => API Key
// "*" is used when no host name is provided
//
// Sample js code for using api
// `const go_response = await fetch("https://go.unl.edu/api/links?token=${API_KEY}", { credentials: "include" });`
$api_access_tokens = array(
"*" => "",
"local-events.unl.edu" => "test",
);

// Define Auth
// Path to system trusted certificates
define('CAS_CA_FILE', '/etc/pki/tls/cert.pem');
Expand Down
47 changes: 46 additions & 1 deletion src/goController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class GoController extends GoRouter {
private $qrIconPNG;
private $qrIconSVG;
private $qrIconSize;
private $apiAccessTokens;
private $flashBag;

// Public State
Expand All @@ -34,13 +35,14 @@ class GoController extends GoRouter {
public static $template;
public static $templateVersion;

public function __construct($lilurl, $auth, $flashBag, $qrIconPNG, $qrIconSVG, $qrIconSize)
public function __construct($lilurl, $auth, $flashBag, $qrIconPNG, $qrIconSVG, $qrIconSize, $apiAccessTokens)
{
$this->lilurl = $lilurl;
$this->auth = $auth;
$this->qrIconPNG = $qrIconPNG;
$this->qrIconSVG = $qrIconSVG;
$this->qrIconSize = $qrIconSize;
$this->apiAccessTokens = $apiAccessTokens;
$this->flashBag = $flashBag;

// See if already logged in via PHP CAS
Expand All @@ -52,6 +54,13 @@ public function __construct($lilurl, $auth, $flashBag, $qrIconPNG, $qrIconSVG, $

private function loginCheck() {
if ($this->routeRequiresLogin() && !$this->auth->isAuthenticated()) {
if ($this->routeNoRedirect()) {
$this->sendCORSHeaders();
header('Content-Type: application/json; charset=utf-8');
header('HTTP/1.1 403 Forbidden');
echo '{ "message": "Forbidden" }';
exit;
}
$this->redirect($this->lilurl->getBaseUrl(self::ROUTE_PATH_LOGIN));
}
}
Expand Down Expand Up @@ -113,6 +122,10 @@ public function dispatch() {
}

switch($this->route) {
case self::ROUTE_NAME_LINKS_API:
$this->handleRouteLinksAPI();
break;

case self::ROUTE_NAME_API:
case self::ROUTE_NAME_HOME:
$this->handleRouteHomePage();
Expand Down Expand Up @@ -503,6 +516,38 @@ private function handleRouteHomePage() {
}
}

private function handleRouteLinksAPI(): void
{
$this->sendCORSHeaders();
header('Content-Type: application/json; charset=utf-8');

if (!$this->auth->isAuthenticated()) {
header('HTTP/1.1 403 Forbidden');
echo '{"message": "Not Logged In"}';
exit;
}

$referer = (string) (parse_url($_SERVER['HTTP_REFERER'] ?? "", PHP_URL_HOST) ?? "*");
$token = (string) ($_GET['token'] ?? "");
$uid = (string) ($this->auth->getUserId() ?? ""); // This could be a url param maybe

if (!isset($this->apiAccessTokens[$referer]) || $this->apiAccessTokens[$referer] != $token) {
header('HTTP/1.1 400 Bad Request');
echo '{"message": "Invalid Token"}';
exit;
}

if (empty($uid)) {
header('HTTP/1.1 400 Bad Request');
echo '{"message": "You need a UID!", "referer": "' . $referer . '"}';
exit;
}

$urls = $this->lilurl->getUserURLs($uid);
echo json_encode($urls);
exit;
}

private function sanitizeURLPost(&$mode, &$userId, &$alias) {
$modeFiltered = htmlspecialchars($_POST['mode'] ?? '');
$mode = $modeFiltered === static::MODE_EDIT ? static::MODE_EDIT : static::MODE_CREATE;
Expand Down
26 changes: 25 additions & 1 deletion src/goRouter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class GoRouter {

// route names
const ROUTE_NAME_API = 'api';
const ROUTE_NAME_LINKS_API = 'link_api';
const ROUTE_NAME_EDIT = 'edit';
const ROUTE_NAME_GROUP = 'group';
const ROUTE_NAME_GROUP_USER_ADD = 'group-user-add';
Expand All @@ -25,6 +26,7 @@ class GoRouter {
// route paths
const ROUTE_PATH_A = 'a/';
const ROUTE_PATH_API = 'api/';
const ROUTE_PATH_LINKS_API = 'api/links';
const ROUTE_PATH_GROUP = 'a/group';
const ROUTE_PATH_GROUP_USER_ADD = 'a/group-user-add';
const ROUTE_PATH_GROUP_USER_REMOVE = 'a/group-user-remove';
Expand All @@ -49,6 +51,7 @@ class GoRouter {
protected function routeRequiresLogin(): bool
{
return in_array($this->route, array(
self::ROUTE_NAME_LINKS_API,
self::ROUTE_NAME_EDIT,
self::ROUTE_NAME_GROUP,
self::ROUTE_NAME_GROUP_USER_ADD,
Expand All @@ -61,6 +64,21 @@ protected function routeRequiresLogin(): bool
));
}

protected function routeNoRedirect(): bool
{
return in_array($this->route, array(
self::ROUTE_NAME_LINKS_API,
));
}

protected function routeRequiresCredentials(): bool
{
return in_array($this->route, array(
self::ROUTE_NAME_LINKS_API,
self::ROUTE_NAME_API,
));
}

public function getViewTemplate() {
return $this->viewTemplate;
}
Expand All @@ -76,7 +94,9 @@ public function route() {
$this->route = self::ROUTE_NAME_HOME;
} elseif ($this->pathInfo === self::ROUTE_PATH_API) {
$this->route = self::ROUTE_NAME_API;
} elseif (preg_match('#^([^/]+)\.qr$#', $this->pathInfo, $matches)) {
} elseif ($this->pathInfo === self::ROUTE_PATH_LINKS_API) {
$this->route = self::ROUTE_NAME_LINKS_API;
}elseif (preg_match('#^([^/]+)\.qr$#', $this->pathInfo, $matches)) {
$this->route = self::ROUTE_NAME_QR_PNG;
$this->goId = $matches[1];
} elseif (preg_match('#^([^/]+)\.png$#', $this->pathInfo, $matches)) {
Expand Down Expand Up @@ -151,6 +171,10 @@ protected function sendCORSHeaders() {
header('Access-Control-Allow-Origin: ' . $allowedCORSDomain);
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: X-Requested-With');

if ($this->routeRequiresCredentials()) {
header('Access-Control-Allow-Credentials: true');
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion www/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
}

$flashBag = new GoFlashBag();
$controller = new GoController($lilurl, $auth, $flashBag, $qrIconPng, $qrIconSvg, $qrIconSize);
$controller = new GoController($lilurl, $auth, $flashBag, $qrIconPng, $qrIconSvg, $qrIconSize, $api_access_tokens);

// do predispatch actions
$controller->preDispatch();
Expand Down