-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #123 from Team-VoW/development
New API feature, content updates, bugfixes
- Loading branch information
Showing
26 changed files
with
430 additions
and
157 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
<?php | ||
|
||
namespace VoicesOfWynn\Controllers\Api\PremiumAuthenticator; | ||
|
||
use VoicesOfWynn\Controllers\Api\ApiController; | ||
use VoicesOfWynn\Models\Api\PremiumAuthenticator\PremiumCodeManager; | ||
|
||
class Authenticator extends ApiController | ||
{ | ||
const STREAM_SERVER_IP = '127.0.0.1'; | ||
|
||
public function process(array $args): int | ||
{ | ||
parse_str(file_get_contents("php://input"),$_INPUT); | ||
$_INPUT = array_merge($_REQUEST, $_INPUT); | ||
|
||
$apiKey = $_INPUT['apiKey'] ?? null; | ||
$discordUserId = $_INPUT['discord'] ?? null; | ||
|
||
if (!in_array($args[0], ['check-code'])) { | ||
if ($apiKey !== self::PREMIUM_AUTHENTICATOR_API_KEY) { | ||
return 401; | ||
} | ||
|
||
if (is_null($discordUserId)) { | ||
return 400; | ||
} | ||
} | ||
|
||
switch ($args[0]) { | ||
case 'check-code': | ||
if ($_SERVER['REQUEST_METHOD'] !== 'GET') { | ||
return 405; | ||
} | ||
|
||
$valid = $this->checkCode(); | ||
$result = ['valid' => ($valid === 200) ? 'true' : 'false']; | ||
if ($valid === 200) { | ||
$result['ip'] = self::STREAM_SERVER_IP; | ||
} else { | ||
$result['reason'] = ($valid === 402) ? 'expired' : 'invalid'; | ||
} | ||
echo json_encode($result); | ||
return 200; | ||
case 'get-code': | ||
if ($_SERVER['REQUEST_METHOD'] !== 'GET') { | ||
return 405; | ||
} | ||
|
||
$result = $this->getCodeForUser($discordUserId); | ||
$status = $result['status']; | ||
$code = $result['code'] ?? null; | ||
if ($status === 404) { | ||
$code = $this->generateCodeForUser($discordUserId); | ||
$status = 201; | ||
} | ||
echo json_encode(["code" => $code]); | ||
return $status; | ||
case 'deactivate-user': | ||
if ($_SERVER['REQUEST_METHOD'] !== 'PUT') { | ||
return 405; | ||
} | ||
|
||
return ($this->deactivateCodeForUser($discordUserId)) ? 204 : 500; | ||
case 'reactivate-user': | ||
if ($_SERVER['REQUEST_METHOD'] !== 'PUT') { | ||
return 405; | ||
} | ||
|
||
return ($this->activateCodeForUser($discordUserId)) ? 204 : 500; | ||
default: | ||
return 400; | ||
} | ||
} | ||
|
||
private function getCodeForUser(string $discordUserId): array | ||
{ | ||
$manager = new PremiumCodeManager(); | ||
$codeInfo = $manager->getCode($discordUserId); | ||
if (is_null($codeInfo)) { | ||
return ['status' => 404]; | ||
} else if (!$codeInfo['active']) { | ||
return ['status' => 402, 'code' => $codeInfo['code']]; | ||
} else { | ||
return ['status' => 200, 'code' => $codeInfo['code']]; | ||
} | ||
} | ||
|
||
private function generateCodeForUser(string $discordUserId): string | ||
{ | ||
$manager = new PremiumCodeManager(); | ||
return $manager->createNew($discordUserId); | ||
} | ||
|
||
private function checkCode(): int | ||
{ | ||
$code = $_REQUEST['code'] ?? null; | ||
if (is_null($code) || strlen($code) !== 16) { | ||
return 400; | ||
} | ||
|
||
$manager = new PremiumCodeManager(); | ||
return $manager->verify($code); | ||
} | ||
|
||
private function deactivateCodeForUser(string $discordUserId): bool | ||
{ | ||
$manager = new PremiumCodeManager(); | ||
return $manager->deactivate($discordUserId); | ||
} | ||
|
||
private function activateCodeForUser(string $discordUserId): bool | ||
{ | ||
$manager = new PremiumCodeManager(); | ||
return $manager->activate($discordUserId); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
namespace VoicesOfWynn\Controllers\Errors; | ||
|
||
class Error402 extends ErrorController | ||
{ | ||
|
||
protected function displayErrorWebsite() | ||
{ | ||
self::$data['error402_title'] = 'Subscription Required'; | ||
self::$data['error402_description'] = 'Oops, you probably didn\'t want to end up here.'; | ||
self::$data['error402_keywords'] = ''; | ||
|
||
self::$view = 'error402'; | ||
} | ||
|
||
protected function sendHttpErrorHeader() | ||
{ | ||
header("HTTP/1.1 402 Payment Required"); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
host=localhost | ||
database=premium-authenticator | ||
username=root | ||
password= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
<?php | ||
|
||
namespace VoicesOfWynn\Models\Api\PremiumAuthenticator; | ||
|
||
|
||
use Exception; | ||
use PDOException; | ||
use VoicesOfWynn\Models\Db; | ||
|
||
class PremiumCodeManager | ||
{ | ||
|
||
/** | ||
* Method generating new premium access code for a single Discord User | ||
* @param string $discordUserId Discord user ID of the user to which the new code should belong (numerical | ||
* string or BIGINT in MySQL) | ||
* @return bool The generated access code, if the new code was generated and saved successfully, FALSE otherwise | ||
*/ | ||
public function createNew(string $discordUserId) | ||
{ | ||
try { | ||
$code = strtoupper(substr(base_convert(bin2hex(random_bytes(11)), 16, 36), 0, 16)); | ||
} catch (Exception $e) { | ||
return false; | ||
} | ||
|
||
try { | ||
$db = new Db('Api/PremiumAuthenticator/DbInfo.ini'); | ||
$result = $db->executeQuery('INSERT INTO access_codes(code,discord_id) VALUES (?,?);', [$code, $discordUserId]); | ||
} catch (PDOException $ex) { | ||
return false; | ||
} | ||
|
||
return $code; | ||
} | ||
|
||
/** | ||
* Method loading an premium access code for the given Discord user | ||
* @param string $discordUserId Discord user ID of the user whose code should be loaded (numerical string or BIGINT | ||
* in MySQL) | ||
* @return array|null Associative array with elements "code" (the 16-character code) and "active" (boolean) or NULL, | ||
* if no code for the user exists | ||
*/ | ||
public function getCode(string $discordUserId): ?array | ||
{ | ||
$db = new Db('Api/PremiumAuthenticator/DbInfo.ini'); | ||
$result = $db->fetchQuery('SELECT code,active FROM access_codes WHERE discord_id = ? LIMIT 1;', [$discordUserId]); | ||
if ($result === false) { | ||
return null; | ||
} | ||
return $result; | ||
} | ||
|
||
/** | ||
* Method checking whether a premium access code is valid | ||
* @param string $code Access code to check | ||
* @return int An HTTP-like code indicator: | ||
* 200 if the code is valid, 402 if the code is disabled, 404 if code does not exist | ||
*/ | ||
public function verify(string $code): int | ||
{ | ||
$code = strtoupper($code); | ||
$db = new Db('Api/PremiumAuthenticator/DbInfo.ini'); | ||
$result = $db->fetchQuery('SELECT active FROM access_codes WHERE code = ? LIMIT 1;', [$code]); | ||
if ($result === false) { | ||
return 404; | ||
} else { | ||
return ($result['active']) ? 200 : 402; | ||
} | ||
} | ||
|
||
/** | ||
* Method marking a certain user's access code as disabled | ||
* @param string $discordUserId Discord ID of the user whose access code should be deactivated | ||
* @return bool TRUE on success, FALSE on failure | ||
*/ | ||
public function deactivate(string $discordUserId) | ||
{ | ||
$db = new Db('Api/PremiumAuthenticator/DbInfo.ini'); | ||
return $db->executeQuery('UPDATE access_codes SET active = 0 WHERE discord_id = ?;', [$discordUserId]); | ||
} | ||
|
||
/** | ||
* Method marking a certain user's access code as enabled | ||
* @param string $discordUserId Discord ID of the user whose access code should be activated | ||
* @return bool TRUE on success, FALSE on failure | ||
*/ | ||
public function activate(string $discordUserId) | ||
{ | ||
$db = new Db('Api/PremiumAuthenticator/DbInfo.ini'); | ||
return $db->executeQuery('UPDATE access_codes SET active = 1 WHERE discord_id = ?;', [$discordUserId]); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.