Added user API key system
This commit is contained in:
parent
ea34d9b756
commit
919a3039c4
6 changed files with 160 additions and 39 deletions
|
@ -805,3 +805,18 @@ function human_filesize(int $bytes, $decimals = 2)
|
||||||
$factor = floor((strlen(strval($bytes)) - 1) / 3);
|
$factor = floor((strlen(strval($bytes)) - 1) / 3);
|
||||||
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @BYTE_DENOMINATIONS[$factor];
|
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @BYTE_DENOMINATIONS[$factor];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generates a unique key for the website to prevent unauthorized access.
|
||||||
|
*/
|
||||||
|
function generate_key(int $length = 20)
|
||||||
|
{
|
||||||
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
$randomString = '';
|
||||||
|
|
||||||
|
for ($i = 0; $i < $length; $i++) {
|
||||||
|
$randomString .= $characters [rand(0, strlen($characters) - 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $randomString;
|
||||||
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ abstract class CronUploaderConfig
|
||||||
$config->set_default_int(self::LOG_LEVEL, SCORE_LOG_INFO);
|
$config->set_default_int(self::LOG_LEVEL, SCORE_LOG_INFO);
|
||||||
$upload_key = $config->get_string(self::KEY, "");
|
$upload_key = $config->get_string(self::KEY, "");
|
||||||
if (empty($upload_key)) {
|
if (empty($upload_key)) {
|
||||||
$upload_key = self::generate_key();
|
$upload_key = generate_key();
|
||||||
|
|
||||||
$config->set_string(self::KEY, $upload_key);
|
$config->set_string(self::KEY, $upload_key);
|
||||||
}
|
}
|
||||||
|
@ -67,21 +67,4 @@ abstract class CronUploaderConfig
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_string(self::DIR, $value);
|
$config->set_string(self::DIR, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generates a unique key for the website to prevent unauthorized access.
|
|
||||||
*/
|
|
||||||
private static function generate_key()
|
|
||||||
{
|
|
||||||
$length = 20;
|
|
||||||
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
||||||
$randomString = '';
|
|
||||||
|
|
||||||
for ($i = 0; $i < $length; $i++) {
|
|
||||||
$randomString .= $characters [rand(0, strlen($characters) - 1)];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $randomString;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,9 +111,9 @@ class SetupBlock extends Block
|
||||||
$this->body .= $content;
|
$this->body .= $content;
|
||||||
$this->end_table_cell();
|
$this->end_table_cell();
|
||||||
}
|
}
|
||||||
public function start_table_header_cell(int $colspan = 1)
|
public function start_table_header_cell(int $colspan = 1, string $align = 'right')
|
||||||
{
|
{
|
||||||
$this->body .= "<th colspan='$colspan'>";
|
$this->body .= "<th colspan='$colspan' style='text-align: $align'>";
|
||||||
}
|
}
|
||||||
public function end_table_header_cell()
|
public function end_table_header_cell()
|
||||||
{
|
{
|
||||||
|
@ -126,23 +126,34 @@ class SetupBlock extends Block
|
||||||
$this->end_table_header_cell();
|
$this->end_table_header_cell();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function format_option(string $name, $html, ?string $label, bool $table_row)
|
private function format_option(
|
||||||
{
|
string $name,
|
||||||
|
$html,
|
||||||
|
?string $label,
|
||||||
|
bool $table_row,
|
||||||
|
bool $label_row = false
|
||||||
|
) {
|
||||||
if ($table_row) {
|
if ($table_row) {
|
||||||
$this->start_table_row();
|
$this->start_table_row();
|
||||||
}
|
}
|
||||||
if ($table_row) {
|
if ($table_row) {
|
||||||
$this->start_table_header_cell();
|
$this->start_table_header_cell($label_row ? 2 : 1, $label_row ? 'center' : 'right');
|
||||||
}
|
}
|
||||||
if (!is_null($label)) {
|
if (!is_null($label)) {
|
||||||
$this->body .= "<label for='{$name}'>{$label}</label>";
|
$this->body .= "<label for='{$name}'>{$label}</label>";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($table_row) {
|
if ($table_row) {
|
||||||
$this->end_table_header_cell();
|
$this->end_table_header_cell();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($table_row && $label_row) {
|
||||||
|
$this->end_table_row();
|
||||||
|
$this->start_table_row();
|
||||||
|
}
|
||||||
|
|
||||||
if ($table_row) {
|
if ($table_row) {
|
||||||
$this->start_table_cell();
|
$this->start_table_cell($label_row ? 2 : 1);
|
||||||
}
|
}
|
||||||
$this->body .= $html;
|
$this->body .= $html;
|
||||||
if ($table_row) {
|
if ($table_row) {
|
||||||
|
@ -173,7 +184,7 @@ class SetupBlock extends Block
|
||||||
$html = "<textarea rows='$rows' id='$name' name='_config_$name'>$val</textarea>\n";
|
$html = "<textarea rows='$rows' id='$name' name='_config_$name'>$val</textarea>\n";
|
||||||
$html .= "<input type='hidden' name='_type_$name' value='string'>\n";
|
$html .= "<input type='hidden' name='_type_$name' value='string'>\n";
|
||||||
|
|
||||||
$this->format_option($name, $html, $label, $table_row);
|
$this->format_option($name, $html, $label, $table_row, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function add_bool_option(string $name, string $label=null, bool $table_row = false)
|
public function add_bool_option(string $name, string $label=null, bool $table_row = false)
|
||||||
|
|
|
@ -276,12 +276,27 @@ class UserPage extends Extension
|
||||||
];
|
];
|
||||||
|
|
||||||
$sb = new SetupBlock("User Options");
|
$sb = new SetupBlock("User Options");
|
||||||
$sb->add_bool_option("login_signup_enabled", "Allow new signups: ");
|
$sb->start_table();
|
||||||
$sb->add_longtext_option("login_tac", "<br>Terms & Conditions:<br>");
|
$sb->add_bool_option(UserConfig::ENABLE_API_KEYS, "Enable user API keys", true);
|
||||||
$sb->add_choice_option("avatar_host", $hosts, "<br>Avatars: ");
|
$sb->add_bool_option("login_signup_enabled", "Allow new signups", true);
|
||||||
|
$sb->add_longtext_option("login_tac", "Terms & Conditions", true);
|
||||||
|
$sb->add_choice_option(
|
||||||
|
"user_loginshowprofile",
|
||||||
|
[
|
||||||
|
"return to previous page" => 0, // 0 is default
|
||||||
|
"send to user profile" => 1],
|
||||||
|
"On log in/out",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
$sb->add_choice_option("avatar_host", $hosts, "Avatars", true);
|
||||||
|
|
||||||
if ($config->get_string("avatar_host") == "gravatar") {
|
if ($config->get_string("avatar_host") == "gravatar") {
|
||||||
$sb->add_label("<br> <br><b>Gravatar Options</b>");
|
$sb->start_table_row();
|
||||||
|
$sb->start_table_cell(2);
|
||||||
|
$sb->add_label("<div style='text-align: center'><b>Gravatar Options</b></div>", );
|
||||||
|
$sb->end_table_cell();
|
||||||
|
$sb->end_table_row();
|
||||||
|
|
||||||
$sb->add_choice_option(
|
$sb->add_choice_option(
|
||||||
"avatar_gravatar_type",
|
"avatar_gravatar_type",
|
||||||
[
|
[
|
||||||
|
@ -290,22 +305,19 @@ class UserPage extends Extension
|
||||||
'Monster ID'=>'monsterid',
|
'Monster ID'=>'monsterid',
|
||||||
'Identicon'=>'identicon'
|
'Identicon'=>'identicon'
|
||||||
],
|
],
|
||||||
"<br>Type: "
|
"Type",
|
||||||
|
true
|
||||||
);
|
);
|
||||||
$sb->add_choice_option(
|
$sb->add_choice_option(
|
||||||
"avatar_gravatar_rating",
|
"avatar_gravatar_rating",
|
||||||
['G'=>'g', 'PG'=>'pg', 'R'=>'r', 'X'=>'x'],
|
['G'=>'g', 'PG'=>'pg', 'R'=>'r', 'X'=>'x'],
|
||||||
"<br>Rating: "
|
"Rating",
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
$sb->end_table();
|
||||||
}
|
}
|
||||||
|
|
||||||
$sb->add_choice_option(
|
|
||||||
"user_loginshowprofile",
|
|
||||||
[
|
|
||||||
"return to previous page" => 0, // 0 is default
|
|
||||||
"send to user profile" => 1],
|
|
||||||
"<br>When user logs in/out"
|
|
||||||
);
|
|
||||||
$event->panel->add_block($sb);
|
$event->panel->add_block($sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,18 @@ class InitUserConfigEvent extends Event
|
||||||
|
|
||||||
class UserConfig extends Extension
|
class UserConfig extends Extension
|
||||||
{
|
{
|
||||||
private const VERSION = "ext_user_config_version";
|
/** @var UserConfigTheme */
|
||||||
|
protected $theme;
|
||||||
|
|
||||||
|
public const VERSION = "ext_user_config_version";
|
||||||
|
public const ENABLE_API_KEYS = "ext_user_config_enable_api_keys";
|
||||||
|
public const API_KEY = "api_key";
|
||||||
|
|
||||||
|
public function onInitExt(InitExtEvent $event)
|
||||||
|
{
|
||||||
|
global $config;
|
||||||
|
$config->set_default_bool(self::ENABLE_API_KEYS, false);
|
||||||
|
}
|
||||||
|
|
||||||
public function onUserLogin(UserLoginEvent $event)
|
public function onUserLogin(UserLoginEvent $event)
|
||||||
{
|
{
|
||||||
|
@ -49,6 +60,66 @@ class UserConfig extends Extension
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onPageRequest(PageRequestEvent $event)
|
||||||
|
{
|
||||||
|
global $user, $database, $config, $page;
|
||||||
|
|
||||||
|
if ($config->get_bool(self::ENABLE_API_KEYS)) {
|
||||||
|
if (!empty($_GET["api_key"]) && $user->is_anonymous()) {
|
||||||
|
$user_id = $database->get_one(
|
||||||
|
"SELECT user_id FROM user_config WHERE value=:value AND name=:name",
|
||||||
|
["value" => $_GET["api_key"], "name" => self::API_KEY]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!empty($user_id)) {
|
||||||
|
$user = User::by_id($user_id);
|
||||||
|
if ($user !== null) {
|
||||||
|
send_event(new UserLoginEvent($user));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global $user_config;
|
||||||
|
|
||||||
|
if ($event->page_matches("user_admin")) {
|
||||||
|
if (!$user->check_auth_token()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch ($event->get_arg(0)) {
|
||||||
|
case "reset_api_key":
|
||||||
|
$user_config->set_string(self::API_KEY, "");
|
||||||
|
|
||||||
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
|
$page->set_redirect(make_link("user"));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onUserOptionsBuilding(UserOptionsBuildingEvent $event)
|
||||||
|
{
|
||||||
|
global $config, $user_config;
|
||||||
|
|
||||||
|
if ($config->get_bool(self::ENABLE_API_KEYS)) {
|
||||||
|
$key = $user_config->get_string(self::API_KEY, "");
|
||||||
|
if (empty($key)) {
|
||||||
|
$key = generate_key();
|
||||||
|
$user_config->set_string(self::API_KEY, $key);
|
||||||
|
}
|
||||||
|
$event->add_html($this->theme->get_user_options($key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onSetupBuilding(SetupBuildingEvent $event)
|
||||||
|
{
|
||||||
|
$sb = new SetupBlock("User Options");
|
||||||
|
$sb->start_table();
|
||||||
|
$sb->end_table();
|
||||||
|
$event->panel->add_block($sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This needs to happen before any other events, but after db upgrade
|
// This needs to happen before any other events, but after db upgrade
|
||||||
public function get_priority(): int
|
public function get_priority(): int
|
||||||
|
|
29
ext/user_config/theme.php
Normal file
29
ext/user_config/theme.php
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
use function MicroHTML\BR;
|
||||||
|
use function MicroHTML\BUTTON;
|
||||||
|
use function MicroHTML\INPUT;
|
||||||
|
|
||||||
|
class UserConfigTheme extends Themelet
|
||||||
|
{
|
||||||
|
|
||||||
|
public function get_user_options(string $key): string
|
||||||
|
{
|
||||||
|
$html = "
|
||||||
|
<p>".make_form(make_link("user_admin/reset_api_key"))."
|
||||||
|
<table style='width: 300px;'>
|
||||||
|
<tbody>
|
||||||
|
<tr><th colspan='2'>API Key</th></tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
$key
|
||||||
|
</td>
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr><td><input type='submit' value='Reset Key'></td></tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
";
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue