Rely on NGINX GeoIP2 module for country code lookup.

This commit is contained in:
flash 2023-07-11 00:25:43 +00:00
parent 575b5e8271
commit f025ee13d0
28 changed files with 101 additions and 461 deletions

View file

@ -2,7 +2,6 @@
"require": {
"twig/twig": "^3.0",
"erusev/parsedown": "~1.6",
"geoip2/geoip2": "~2.0",
"chillerlan/php-qrcode": "^4.3",
"whichbrowser/parser": "^2.0",
"symfony/mailer": "^6.0"

351
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "b3b6cf189969ecb1dd838c23a4fe96e1",
"content-hash": "26152622b2776a8d945647d5c1cfc48c",
"packages": [
{
"name": "chillerlan/php-qrcode",
@ -148,82 +148,6 @@
],
"time": "2022-07-05T22:32:14+00:00"
},
{
"name": "composer/ca-bundle",
"version": "1.3.5",
"source": {
"type": "git",
"url": "https://github.com/composer/ca-bundle.git",
"reference": "74780ccf8c19d6acb8d65c5f39cd72110e132bbd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/74780ccf8c19d6acb8d65c5f39cd72110e132bbd",
"reference": "74780ccf8c19d6acb8d65c5f39cd72110e132bbd",
"shasum": ""
},
"require": {
"ext-openssl": "*",
"ext-pcre": "*",
"php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.55",
"psr/log": "^1.0",
"symfony/phpunit-bridge": "^4.2 || ^5",
"symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Composer\\CaBundle\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
}
],
"description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
"keywords": [
"cabundle",
"cacert",
"certificate",
"ssl",
"tls"
],
"support": {
"irc": "irc://irc.freenode.org/composer",
"issues": "https://github.com/composer/ca-bundle/issues",
"source": "https://github.com/composer/ca-bundle/tree/1.3.5"
},
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"time": "2023-01-11T08:27:00+00:00"
},
{
"name": "doctrine/lexer",
"version": "3.0.0",
@ -418,176 +342,6 @@
},
"time": "2019-12-30T22:54:17+00:00"
},
{
"name": "geoip2/geoip2",
"version": "v2.13.0",
"source": {
"type": "git",
"url": "git@github.com:maxmind/GeoIP2-php.git",
"reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/6a41d8fbd6b90052bc34dff3b4252d0f88067b23",
"reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23",
"shasum": ""
},
"require": {
"ext-json": "*",
"maxmind-db/reader": "~1.8",
"maxmind/web-service-common": "~0.8",
"php": ">=7.2"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "3.*",
"phpstan/phpstan": "*",
"phpunit/phpunit": "^8.0 || ^9.0",
"squizlabs/php_codesniffer": "3.*"
},
"type": "library",
"autoload": {
"psr-4": {
"GeoIp2\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Gregory J. Oschwald",
"email": "goschwald@maxmind.com",
"homepage": "https://www.maxmind.com/"
}
],
"description": "MaxMind GeoIP2 PHP API",
"homepage": "https://github.com/maxmind/GeoIP2-php",
"keywords": [
"IP",
"geoip",
"geoip2",
"geolocation",
"maxmind"
],
"time": "2022-08-05T20:32:58+00:00"
},
{
"name": "maxmind-db/reader",
"version": "v1.11.0",
"source": {
"type": "git",
"url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
"reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/b1f3c0699525336d09cc5161a2861268d9f2ae5b",
"reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"conflict": {
"ext-maxminddb": "<1.10.1,>=2.0.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "3.*",
"php-coveralls/php-coveralls": "^2.1",
"phpstan/phpstan": "*",
"phpunit/phpcov": ">=6.0.0",
"phpunit/phpunit": ">=8.0.0,<10.0.0",
"squizlabs/php_codesniffer": "3.*"
},
"suggest": {
"ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
"ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
"ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
},
"type": "library",
"autoload": {
"psr-4": {
"MaxMind\\Db\\": "src/MaxMind/Db"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Gregory J. Oschwald",
"email": "goschwald@maxmind.com",
"homepage": "https://www.maxmind.com/"
}
],
"description": "MaxMind DB Reader API",
"homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php",
"keywords": [
"database",
"geoip",
"geoip2",
"geolocation",
"maxmind"
],
"support": {
"issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues",
"source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.11.0"
},
"time": "2021-10-18T15:23:10+00:00"
},
{
"name": "maxmind/web-service-common",
"version": "v0.9.0",
"source": {
"type": "git",
"url": "https://github.com/maxmind/web-service-common-php.git",
"reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/4dc5a3e8df38aea4ca3b1096cee3a038094e9b53",
"reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53",
"shasum": ""
},
"require": {
"composer/ca-bundle": "^1.0.3",
"ext-curl": "*",
"ext-json": "*",
"php": ">=7.2"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "3.*",
"phpstan/phpstan": "*",
"phpunit/phpunit": "^8.0 || ^9.0",
"squizlabs/php_codesniffer": "3.*"
},
"type": "library",
"autoload": {
"psr-4": {
"MaxMind\\Exception\\": "src/Exception",
"MaxMind\\WebService\\": "src/WebService"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Gregory Oschwald",
"email": "goschwald@maxmind.com"
}
],
"description": "Internal MaxMind Web Service API",
"homepage": "https://github.com/maxmind/web-service-common-php",
"support": {
"issues": "https://github.com/maxmind/web-service-common-php/issues",
"source": "https://github.com/maxmind/web-service-common-php/tree/v0.9.0"
},
"time": "2022-03-28T17:43:20+00:00"
},
{
"name": "psr/cache",
"version": "3.0.0",
@ -792,24 +546,25 @@
},
{
"name": "symfony/event-dispatcher",
"version": "v6.2.7",
"version": "v6.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "404b307de426c1c488e5afad64403e5f145e82a5"
"reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/404b307de426c1c488e5afad64403e5f145e82a5",
"reference": "404b307de426c1c488e5afad64403e5f145e82a5",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa",
"reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa",
"shasum": ""
},
"require": {
"php": ">=8.1",
"symfony/event-dispatcher-contracts": "^2|^3"
"symfony/event-dispatcher-contracts": "^2.5|^3"
},
"conflict": {
"symfony/dependency-injection": "<5.4"
"symfony/dependency-injection": "<5.4",
"symfony/service-contracts": "<2.5"
},
"provide": {
"psr/event-dispatcher-implementation": "1.0",
@ -822,13 +577,9 @@
"symfony/error-handler": "^5.4|^6.0",
"symfony/expression-language": "^5.4|^6.0",
"symfony/http-foundation": "^5.4|^6.0",
"symfony/service-contracts": "^1.1|^2|^3",
"symfony/service-contracts": "^2.5|^3",
"symfony/stopwatch": "^5.4|^6.0"
},
"suggest": {
"symfony/dependency-injection": "",
"symfony/http-kernel": ""
},
"type": "library",
"autoload": {
"psr-4": {
@ -855,7 +606,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v6.2.7"
"source": "https://github.com/symfony/event-dispatcher/tree/v6.3.0"
},
"funding": [
{
@ -871,33 +622,30 @@
"type": "tidelift"
}
],
"time": "2023-02-14T08:44:56+00:00"
"time": "2023-04-21T14:41:17+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
"version": "v3.2.1",
"version": "v3.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
"reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd"
"reference": "a76aed96a42d2b521153fb382d418e30d18b59df"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ad3b6f1e4e2da5690fefe075cd53a238646d8dd",
"reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd",
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df",
"reference": "a76aed96a42d2b521153fb382d418e30d18b59df",
"shasum": ""
},
"require": {
"php": ">=8.1",
"psr/event-dispatcher": "^1"
},
"suggest": {
"symfony/event-dispatcher-implementation": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.3-dev"
"dev-main": "3.4-dev"
},
"thanks": {
"name": "symfony/contracts",
@ -934,7 +682,7 @@
"standards"
],
"support": {
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.2.1"
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0"
},
"funding": [
{
@ -950,20 +698,20 @@
"type": "tidelift"
}
],
"time": "2023-03-01T10:32:47+00:00"
"time": "2023-05-23T14:45:45+00:00"
},
{
"name": "symfony/mailer",
"version": "v6.2.7",
"version": "v6.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
"reference": "e4f84c633b72ec70efc50b8016871c3bc43e691e"
"reference": "7b03d9be1dea29bfec0a6c7b603f5072a4c97435"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mailer/zipball/e4f84c633b72ec70efc50b8016871c3bc43e691e",
"reference": "e4f84c633b72ec70efc50b8016871c3bc43e691e",
"url": "https://api.github.com/repos/symfony/mailer/zipball/7b03d9be1dea29bfec0a6c7b603f5072a4c97435",
"reference": "7b03d9be1dea29bfec0a6c7b603f5072a4c97435",
"shasum": ""
},
"require": {
@ -973,9 +721,10 @@
"psr/log": "^1|^2|^3",
"symfony/event-dispatcher": "^5.4|^6.0",
"symfony/mime": "^6.2",
"symfony/service-contracts": "^1.1|^2|^3"
"symfony/service-contracts": "^2.5|^3"
},
"conflict": {
"symfony/http-client-contracts": "<2.5",
"symfony/http-kernel": "<5.4",
"symfony/messenger": "<6.2",
"symfony/mime": "<6.2",
@ -1013,7 +762,7 @@
"description": "Helps sending emails",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/mailer/tree/v6.2.7"
"source": "https://github.com/symfony/mailer/tree/v6.3.0"
},
"funding": [
{
@ -1029,20 +778,20 @@
"type": "tidelift"
}
],
"time": "2023-02-21T10:35:38+00:00"
"time": "2023-05-29T12:49:39+00:00"
},
{
"name": "symfony/mime",
"version": "v6.2.7",
"version": "v6.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
"reference": "62e341f80699badb0ad70b31149c8df89a2d778e"
"reference": "7b5d2121858cd6efbed778abce9cfdd7ab1f62ad"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/62e341f80699badb0ad70b31149c8df89a2d778e",
"reference": "62e341f80699badb0ad70b31149c8df89a2d778e",
"url": "https://api.github.com/repos/symfony/mime/zipball/7b5d2121858cd6efbed778abce9cfdd7ab1f62ad",
"reference": "7b5d2121858cd6efbed778abce9cfdd7ab1f62ad",
"shasum": ""
},
"require": {
@ -1096,7 +845,7 @@
"mime-type"
],
"support": {
"source": "https://github.com/symfony/mime/tree/v6.2.7"
"source": "https://github.com/symfony/mime/tree/v6.3.0"
},
"funding": [
{
@ -1112,7 +861,7 @@
"type": "tidelift"
}
],
"time": "2023-02-24T10:42:00+00:00"
"time": "2023-04-28T15:57:00+00:00"
},
{
"name": "symfony/polyfill-ctype",
@ -1528,16 +1277,16 @@
},
{
"name": "symfony/service-contracts",
"version": "v3.2.1",
"version": "v3.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "a8c9cedf55f314f3a186041d19537303766df09a"
"reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/a8c9cedf55f314f3a186041d19537303766df09a",
"reference": "a8c9cedf55f314f3a186041d19537303766df09a",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
"reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
"shasum": ""
},
"require": {
@ -1547,13 +1296,10 @@
"conflict": {
"ext-psr": "<1.1|>=2"
},
"suggest": {
"symfony/service-implementation": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.3-dev"
"dev-main": "3.4-dev"
},
"thanks": {
"name": "symfony/contracts",
@ -1593,7 +1339,7 @@
"standards"
],
"support": {
"source": "https://github.com/symfony/service-contracts/tree/v3.2.1"
"source": "https://github.com/symfony/service-contracts/tree/v3.3.0"
},
"funding": [
{
@ -1609,20 +1355,20 @@
"type": "tidelift"
}
],
"time": "2023-03-01T10:32:47+00:00"
"time": "2023-05-23T14:45:45+00:00"
},
{
"name": "twig/twig",
"version": "v3.5.1",
"version": "v3.6.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "a6e0510cc793912b451fd40ab983a1d28f611c15"
"reference": "7e7d5839d4bec168dfeef0ac66d5c5a2edbabffd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a6e0510cc793912b451fd40ab983a1d28f611c15",
"reference": "a6e0510cc793912b451fd40ab983a1d28f611c15",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/7e7d5839d4bec168dfeef0ac66d5c5a2edbabffd",
"reference": "7e7d5839d4bec168dfeef0ac66d5c5a2edbabffd",
"shasum": ""
},
"require": {
@ -1631,15 +1377,10 @@
"symfony/polyfill-mbstring": "^1.3"
},
"require-dev": {
"psr/container": "^1.0",
"psr/container": "^1.0|^2.0",
"symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.5-dev"
}
},
"autoload": {
"psr-4": {
"Twig\\": "src/"
@ -1673,7 +1414,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.5.1"
"source": "https://github.com/twigphp/Twig/tree/v3.6.1"
},
"funding": [
{
@ -1685,7 +1426,7 @@
"type": "tidelift"
}
],
"time": "2023-02-08T07:49:20+00:00"
"time": "2023-06-08T12:52:13+00:00"
},
{
"name": "whichbrowser/parser",

View file

@ -7,7 +7,6 @@ use Index\Data\ConnectionFailedException;
use Index\Data\DbTools;
use Misuzu\Config\IConfig;
use Misuzu\Config\DbConfig;
use Misuzu\Net\IPAddress;
use Misuzu\Users\User;
use Misuzu\Users\UserNotFoundException;
use Misuzu\Users\UserSession;
@ -127,8 +126,6 @@ if(!is_readable(MSZ_STORAGE) || !is_writable(MSZ_STORAGE)) {
exit;
}
IPAddress::init($msz);
if(!MSZ_DEBUG) {
$twigCacheDirSfx = GitInfo::hash(true);
if(empty($twigCacheDirSfx))

View file

@ -42,6 +42,7 @@ if(!empty($_GET['resolve'])) {
$notices = [];
$ipAddress = $_SERVER['REMOTE_ADDR'];
$countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX';
$siteIsPrivate = $cfg->getValue('private.enable', IConfig::T_BOOL);
$loginPermCat = $siteIsPrivate ? $cfg->getValue('private.perm.cat', IConfig::T_STR) : '';
$loginPermVal = $siteIsPrivate ? $cfg->getValue('private.perm.val', IConfig::T_INT) : 0;
@ -76,7 +77,7 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
try {
$userInfo = User::byUsernameOrEMailAddress($_POST['login']['username']);
} catch(UserNotFoundException $ex) {
UserLoginAttempt::create($ipAddress, false);
UserLoginAttempt::create($ipAddress, $countryCode, false);
$notices[] = $loginFailedError;
break;
}
@ -87,7 +88,7 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
}
if($userInfo->isDeleted() || !$userInfo->checkPassword($_POST['login']['password'])) {
UserLoginAttempt::create($ipAddress, false, $userInfo);
UserLoginAttempt::create($ipAddress, $countryCode, false, $userInfo);
$notices[] = $loginFailedError;
break;
}
@ -97,7 +98,7 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
if(!empty($loginPermCat) && $loginPermVal > 0 && !perms_check_user($loginPermCat, $userInfo->getId(), $loginPermVal)) {
$notices[] = "Login succeeded, but you're not allowed to browse the site right now.";
UserLoginAttempt::create($ipAddress, true, $userInfo);
UserLoginAttempt::create($ipAddress, $countryCode, true, $userInfo);
break;
}
@ -108,10 +109,10 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
return;
}
UserLoginAttempt::create($ipAddress, true, $userInfo);
UserLoginAttempt::create($ipAddress, $countryCode, true, $userInfo);
try {
$sessionInfo = UserSession::create($userInfo, $ipAddress);
$sessionInfo = UserSession::create($userInfo, $ipAddress, $countryCode);
$sessionInfo->setCurrent();
} catch(UserSessionCreationFailedException $ex) {
$notices[] = "Something broke while creating a session for you, please tell an administrator or developer about this!";

View file

@ -79,7 +79,7 @@ while($canResetPassword) {
->removeTOTPKey()
->save();
AuditLog::create($ipAddress, AuditLog::PASSWORD_RESET, [], $userInfo);
AuditLog::create(AuditLog::PASSWORD_RESET, [], $userInfo);
$tokenInfo->invalidate();

View file

@ -18,6 +18,7 @@ if(UserSession::hasCurrent()) {
$register = !empty($_POST['register']) && is_array($_POST['register']) ? $_POST['register'] : [];
$notices = [];
$ipAddress = $_SERVER['REMOTE_ADDR'];
$countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX';
$remainingAttempts = UserLoginAttempt::remaining($_SERVER['REMOTE_ADDR']);
$restricted = UserWarning::countByRemoteAddress($ipAddress) > 0 ? 'ban' : '';
@ -78,7 +79,8 @@ while(!$restricted && !empty($register)) {
$register['username'],
$register['password'],
$register['email'],
$ipAddress
$ipAddress,
$countryCode
);
} catch(UserCreationFailedException $ex) {
$notices[] = 'Something went wrong while creating your account, please alert an administrator or a developer about this!';

View file

@ -16,6 +16,7 @@ if(UserSession::hasCurrent()) {
}
$ipAddress = $_SERVER['REMOTE_ADDR'];
$countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX';
$twofactor = !empty($_POST['twofactor']) && is_array($_POST['twofactor']) ? $_POST['twofactor'] : [];
$notices = [];
$remainingAttempts = UserLoginAttempt::remaining($ipAddress);
@ -67,15 +68,15 @@ while(!empty($twofactor)) {
$remainingAttempts - 1,
$remainingAttempts === 2 ? '' : 's'
);
UserLoginAttempt::create($ipAddress, false, $userInfo);
UserLoginAttempt::create($ipAddress, $countryCode, false, $userInfo);
break;
}
UserLoginAttempt::create($ipAddress, true, $userInfo);
UserLoginAttempt::create($ipAddress, $countryCode, true, $userInfo);
$tokenInfo->delete();
try {
$sessionInfo = UserSession::create($userInfo, $ipAddress);
$sessionInfo = UserSession::create($userInfo, $ipAddress, $countryCode);
$sessionInfo->setCurrent();
} catch(UserSessionCreationFailedException $ex) {
$notices[] = "Something broke while creating a session for you, please tell an administrator or developer about this!";

View file

@ -138,13 +138,13 @@ switch($commentMode) {
$commentInfo2->save();
if($isModAction) {
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::COMMENT_ENTRY_DELETE_MOD, [
AuditLog::create(AuditLog::COMMENT_ENTRY_DELETE_MOD, [
$commentInfo2->getId(),
$commentUserId = $commentInfo2->getUserId(),
($commentUserId < 1 ? '(Deleted User)' : $commentInfo2->getUser()->getUsername()),
]);
} else {
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::COMMENT_ENTRY_DELETE, [$commentInfo2->getId()]);
AuditLog::create(AuditLog::COMMENT_ENTRY_DELETE, [$commentInfo2->getId()]);
}
redirect($redirect);
@ -164,7 +164,7 @@ switch($commentMode) {
$commentInfo2->setDeleted(false);
$commentInfo2->save();
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::COMMENT_ENTRY_RESTORE, [
AuditLog::create(AuditLog::COMMENT_ENTRY_RESTORE, [
$commentInfo2->getId(),
$commentUserId = $commentInfo2->getUserId(),
($commentUserId < 1 ? '(Deleted User)' : $commentInfo2->getUser()->getUsername()),

View file

@ -104,7 +104,7 @@ switch($postMode) {
$deletePost = forum_post_delete($postInfo['post_id']);
if($deletePost) {
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_POST_DELETE, [$postInfo['post_id']]);
AuditLog::create(AuditLog::FORUM_POST_DELETE, [$postInfo['post_id']]);
}
if(!$deletePost) {
@ -147,7 +147,7 @@ switch($postMode) {
break;
}
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_POST_NUKE, [$postInfo['post_id']]);
AuditLog::create(AuditLog::FORUM_POST_NUKE, [$postInfo['post_id']]);
url_redirect('forum-topic', ['topic' => $postInfo['topic_id']]);
break;
@ -184,7 +184,7 @@ switch($postMode) {
break;
}
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_POST_RESTORE, [$postInfo['post_id']]);
AuditLog::create(AuditLog::FORUM_POST_RESTORE, [$postInfo['post_id']]);
url_redirect('forum-topic', ['topic' => $postInfo['topic_id']]);
break;

View file

@ -166,7 +166,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
$deleteTopic = forum_topic_delete($topic['topic_id']);
if($deleteTopic)
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_DELETE, [$topic['topic_id']]);
AuditLog::create(AuditLog::FORUM_TOPIC_DELETE, [$topic['topic_id']]);
if(!$deleteTopic) {
echo render_error(500);
@ -209,7 +209,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
break;
}
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_RESTORE, [$topic['topic_id']]);
AuditLog::create(AuditLog::FORUM_TOPIC_RESTORE, [$topic['topic_id']]);
url_redirect('forum-category', [
'forum' => $topic['forum_id'],
@ -247,7 +247,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
break;
}
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_NUKE, [$topic['topic_id']]);
AuditLog::create(AuditLog::FORUM_TOPIC_NUKE, [$topic['topic_id']]);
url_redirect('forum-category', [
'forum' => $topic['forum_id'],
@ -256,7 +256,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
case 'bump':
if($canBumpTopic && forum_topic_bump($topic['topic_id'])) {
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_BUMP, [$topic['topic_id']]);
AuditLog::create(AuditLog::FORUM_TOPIC_BUMP, [$topic['topic_id']]);
}
url_redirect('forum-topic', [
@ -266,7 +266,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
case 'lock':
if($canLockTopic && !$topicIsLocked && forum_topic_lock($topic['topic_id'])) {
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_LOCK, [$topic['topic_id']]);
AuditLog::create(AuditLog::FORUM_TOPIC_LOCK, [$topic['topic_id']]);
}
url_redirect('forum-topic', [
@ -276,7 +276,7 @@ if(in_array($moderationMode, $validModerationModes, true)) {
case 'unlock':
if($canLockTopic && $topicIsLocked && forum_topic_unlock($topic['topic_id'])) {
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_UNLOCK, [$topic['topic_id']]);
AuditLog::create(AuditLog::FORUM_TOPIC_UNLOCK, [$topic['topic_id']]);
}
url_redirect('forum-topic', [

View file

@ -60,7 +60,6 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
->save();
AuditLog::create(
$_SERVER['REMOTE_ADDR'],
empty($isNew)
? AuditLog::CHANGELOG_ENTRY_EDIT
: AuditLog::CHANGELOG_ENTRY_CREATE,

View file

@ -35,7 +35,6 @@ if(!empty($_POST['tag']) && is_array($_POST['tag']) && CSRF::validateRequest())
->save();
AuditLog::create(
$_SERVER['REMOTE_ADDR'],
empty($isNew)
? AuditLog::CHANGELOG_TAG_EDIT
: AuditLog::CHANGELOG_TAG_CREATE,

View file

@ -20,7 +20,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') {
if($rTopicId < 1)
throw new \Exception("Invalid topic id.");
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_REDIR_CREATE, [$rTopicId]);
AuditLog::create(AuditLog::FORUM_TOPIC_REDIR_CREATE, [$rTopicId]);
forum_topic_redir_create($rTopicId, User::getCurrent()->getId(), $rTopicURL);
url_redirect('manage-forum-topic-redirs');
return;
@ -31,7 +31,7 @@ if(filter_input(INPUT_GET, 'm') === 'explode') {
throw new \Exception("Request verification failed.");
$rTopicId = (int)filter_input(INPUT_GET, 't');
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::FORUM_TOPIC_REDIR_REMOVE, [$rTopicId]);
AuditLog::create(AuditLog::FORUM_TOPIC_REDIR_REMOVE, [$rTopicId]);
forum_topic_redir_remove($rTopicId);
url_redirect('manage-forum-topic-redirs');
return;

View file

@ -22,7 +22,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') {
if(!CSRF::validateRequest())
throw new \Exception("Request verification failed.");
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::CONFIG_DELETE, [$sName]);
AuditLog::create(AuditLog::CONFIG_DELETE, [$sName]);
$cfg->removeValue($sName);
url_redirect('manage-general-settings');
} else {

View file

@ -95,7 +95,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') {
$sVar['value'] = $sValue;
AuditLog::create($_SERVER['REMOTE_ADDR'], $sLogAction, [$sName]);
AuditLog::create($sLogAction, [$sName]);
$cfg->setValue($sName, $sValue);
url_redirect('manage-general-settings');
return;

View file

@ -36,7 +36,6 @@ if(!empty($_POST['category']) && CSRF::validateRequest()) {
->save();
AuditLog::create(
$_SERVER['REMOTE_ADDR'],
empty($isNew)
? AuditLog::NEWS_CATEGORY_EDIT
: AuditLog::NEWS_CATEGORY_CREATE,

View file

@ -44,7 +44,6 @@ if(!empty($_POST['post']) && CSRF::validateRequest()) {
$postInfo->save();
AuditLog::create(
$_SERVER['REMOTE_ADDR'],
empty($isNew)
? AuditLog::NEWS_POST_EDIT
: AuditLog::NEWS_POST_CREATE,

View file

@ -103,7 +103,7 @@ if($isVerifiedRequest && !empty($_POST['current_password'])) {
}
} else {
$currentUser->setEMailAddress($_POST['email']['new']);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::PERSONAL_EMAIL_CHANGE, [
AuditLog::create(AuditLog::PERSONAL_EMAIL_CHANGE, [
$_POST['email']['new'],
]);
}
@ -121,7 +121,7 @@ if($isVerifiedRequest && !empty($_POST['current_password'])) {
$errors[] = 'The given passwords was too weak.';
} else {
$currentUser->setPassword($_POST['password']['new']);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::PERSONAL_PASSWORD_CHANGE);
AuditLog::create(AuditLog::PERSONAL_PASSWORD_CHANGE);
}
}
}

View file

@ -36,7 +36,7 @@ if(isset($_POST['action']) && is_string($_POST['action'])) {
&& $currentUser->checkPassword($_POST['password'] ?? '')) {
switch($_POST['action']) {
case 'data':
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::PERSONAL_DATA_DOWNLOAD);
AuditLog::create(AuditLog::PERSONAL_DATA_DOWNLOAD);
$timeStamp = floor(time() / 3600) * 3600;
$fileName = sprintf('msz-user-data-%d-%d.zip', $currentUserId, $timeStamp);

View file

@ -38,12 +38,12 @@ if(!empty($_POST['session']) && CSRF::validateRequest()) {
}
$sessionInfo->delete();
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::PERSONAL_SESSION_DESTROY, [$sessionInfo->getId()]);
AuditLog::create(AuditLog::PERSONAL_SESSION_DESTROY, [$sessionInfo->getId()]);
}
} elseif($_POST['session'] === 'all') {
$currentSessionKilled = true;
UserSession::purgeUser($currentUser);
AuditLog::create($_SERVER['REMOTE_ADDR'], AuditLog::PERSONAL_SESSION_DESTROY_ALL);
AuditLog::create(AuditLog::PERSONAL_SESSION_DESTROY_ALL);
}
if($currentSessionKilled) {

View file

@ -3,7 +3,6 @@ namespace Misuzu;
use Misuzu\DB;
use Misuzu\Pagination;
use Misuzu\Net\IPAddress;
use Misuzu\Users\User;
use Misuzu\Users\UserNotFoundException;
@ -159,16 +158,19 @@ class AuditLog {
return vsprintf(self::FORMATS[$this->getAction()], $this->getParams());
}
public static function create(string $remoteAddr, string $action, array $params = [], ?User $user = null): void {
public static function create(string $action, array $params = [], ?User $user = null): void {
$user = $user ?? User::getCurrent();
$remoteAddr = $_SERVER['REMOTE_ADDR'] ?? '::1';
$countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX';
$createLog = DB::prepare(
'INSERT INTO `' . DB::PREFIX . self::TABLE . '` (`log_action`, `user_id`, `log_params`, `log_ip`, `log_country`)'
. ' VALUES (:action, :user, :params, INET6_ATON(:ip), :country)'
) ->bind('action', $action)
->bind('user', $user === null ? null : $user->getId()) // this null situation should never ever happen but better safe than sorry !
->bind('user', $user === null ? null : $user->getId())
->bind('params', json_encode($params))
->bind('ip', $remoteAddr)
->bind('country', IPAddress::country($remoteAddr))
->bind('country', $countryCode)
->execute();
}

View file

@ -1,76 +0,0 @@
<?php
namespace Misuzu\GeoIP;
use InvalidArgumentException;
use RuntimeException;
use Index\Net\IPAddress;
use GeoIp2\Database\Reader;
use GeoIp2\Exception\AddressNotFoundException;
use GeoIp2\Model\Asn;
use GeoIp2\Model\City;
use GeoIp2\Model\Country;
use Misuzu\Config\IConfig;
class GeoIPHelper {
public const ASN = 'asn';
public const CITY = 'city';
public const COUNTRY = 'country';
private IConfig $config;
private array $readers = [];
public function __construct(IConfig $config) {
$this->config = $config;
}
public function hasDbPath(string $type): bool {
return array_key_exists($type, $this->readers)
|| $this->config->hasValue('db.' . $type);
}
public function getDbPath(string $type): string {
$type = 'db.' . $type;
if(!$this->config->hasValue($type))
throw new RuntimeException('Not database path has been configured for $type.');
return $this->config->getValue($type, IConfig::T_STR);
}
public function getReader(string $type): Reader {
if(!array_key_exists($type, $this->readers))
return $this->readers[$type] = new Reader($this->getDbPath($type));
return $this->readers[$type];
}
public function getASN(IPAddress|string $ipAddress): Asn {
if($ipAddress instanceof IPAddress)
$ipAddress = $ipAddress->getCleanAddress();
if($this->hasDbPath(self::ASN))
return $this->getReader(self::ASN)->asn($ipAddress);
throw new RuntimeException('There was no database available that could satisfy this request.');
}
public function getCityOrCountry(IPAddress|string $ipAddress): City|Country {
if($ipAddress instanceof IPAddress)
$ipAddress = $ipAddress->getCleanAddress();
if($this->hasDbPath(self::CITY))
return $this->getReader(self::CITY)->city($ipAddress);
if($this->hasDbPath(self::COUNTRY))
return $this->getReader(self::COUNTRY)->country($ipAddress);
throw new RuntimeException('There was no database available that could satisfy this request.');
}
public function getIsoCountryCode(IPAddress|string $ipAddress, string $fallback = 'XX'): string {
try {
return $this->getCityOrCountry($ipAddress)->country->isoCode ?? $fallback;
} catch(AddressNotFoundException $ex) {
return $fallback;
} catch(RuntimeException $ex) {
return $fallback;
}
}
}

View file

@ -3,7 +3,6 @@ namespace Misuzu;
use Misuzu\Template;
use Misuzu\Config\IConfig;
use Misuzu\GeoIP\GeoIPHelper;
use Misuzu\SharpChat\SharpChatRoutes;
use Misuzu\Users\Users;
use Index\Data\IDbConnection;
@ -22,7 +21,6 @@ class MisuzuContext {
private IConfig $config;
private Users $users;
private HttpFx $router;
private ?GeoIPHelper $geoIP = null;
public function __construct(IDbConnection $dbConn, IConfig $config) {
$this->dbConn = $dbConn;
@ -59,12 +57,6 @@ class MisuzuContext {
return $this->users;
}*/
public function getGeoIP(): GeoIPHelper {
if($this->geoIP === null)
return $this->geoIP = new GeoIPHelper($this->config->scopeTo('geoip'));
return $this->geoIP;
}
public function setUpHttp(bool $legacy = false): void {
$this->router = new HttpFx;
$this->router->use('/', function($response) {

View file

@ -1,19 +0,0 @@
<?php
namespace Misuzu\Net;
use Misuzu\MisuzuContext;
// remains for now for backwards compatibility with existing ::create methods
// plan is for those ::create methods to Fucking Die so that's fine for now
final class IPAddress {
private static MisuzuContext $context;
public static function init(MisuzuContext $ctx): void {
self::$context = $ctx;
}
public static function country(string $address, string $fallback = 'XX'): string {
return self::$context->getGeoIP()->getIsoCountryCode($address, $fallback);
}
}

View file

@ -10,7 +10,6 @@ use Misuzu\HasRankInterface;
use Misuzu\Memoizer;
use Misuzu\Pagination;
use Misuzu\TOTP;
use Misuzu\Net\IPAddress;
use Misuzu\Parsers\Parser;
use Misuzu\Users\Assets\UserAvatarAsset;
use Misuzu\Users\Assets\UserBackgroundAsset;
@ -732,7 +731,8 @@ class User implements HasRankInterface {
string $username,
string $password,
string $email,
string $ipAddress
string $ipAddress,
string $countryCode = 'XX'
): self {
$createUser = DB::prepare(
'INSERT INTO `' . DB::PREFIX . self::TABLE . '` (`username`, `password`, `email`, `register_ip`, `last_ip`, `user_country`, `display_role`)'
@ -742,7 +742,7 @@ class User implements HasRankInterface {
->bind('register_ip', $ipAddress)
->bind('last_ip', $ipAddress)
->bind('password', self::hashPassword($password))
->bind('user_country', IPAddress::country($ipAddress))
->bind('user_country', $countryCode)
->executeGetId();
if($createUser < 1)

View file

@ -3,7 +3,6 @@ namespace Misuzu\Users;
use Misuzu\DB;
use Misuzu\Pagination;
use Misuzu\Net\IPAddress;
use WhichBrowser\Parser as UserAgentParser;
class UserLoginAttempt {
@ -77,15 +76,22 @@ class UserLoginAttempt {
->fetchColumn();
}
public static function create(string $remoteAddr, bool $success, ?User $user = null, string $userAgent = null): void {
public static function create(
string $remoteAddr,
string $countryCode,
bool $success,
?User $user = null,
string $userAgent = null
): void {
$userAgent = $userAgent ?? filter_input(INPUT_SERVER, 'HTTP_USER_AGENT') ?? '';
$createLog = DB::prepare(
'INSERT INTO `' . DB::PREFIX . self::TABLE . '` (`user_id`, `attempt_success`, `attempt_ip`, `attempt_country`, `attempt_user_agent`)'
. ' VALUES (:user, :success, INET6_ATON(:ip), :country, :user_agent)'
) ->bind('user', $user === null ? null : $user->getId()) // this null situation should never ever happen but better safe than sorry !
->bind('success', $success ? 1 : 0)
->bind('ip', $remoteAddr)
->bind('country', IPAddress::country($remoteAddr))
->bind('country', $countryCode)
->bind('user_agent', $userAgent)
->execute();
}

View file

@ -2,7 +2,6 @@
namespace Misuzu\Users;
use Misuzu\DB;
use Misuzu\Net\IPAddress;
class UserRecoveryTokenException extends UsersException {}
class UserRecoveryTokenNotFoundException extends UserRecoveryTokenException {}

View file

@ -3,7 +3,6 @@ namespace Misuzu\Users;
use Misuzu\DB;
use Misuzu\Pagination;
use Misuzu\Net\IPAddress;
use WhichBrowser\Parser as UserAgentParser;
class UserSessionException extends UsersException {}
@ -174,7 +173,7 @@ class UserSession {
->execute();
}
public static function create(User $user, string $remoteAddr, ?string $userAgent = null, ?string $token = null): self {
public static function create(User $user, string $remoteAddr, string $countryCode, ?string $userAgent = null, ?string $token = null): self {
$userAgent = $userAgent ?? filter_input(INPUT_SERVER, 'HTTP_USER_AGENT') ?? '';
$token = $token ?? self::generateToken();
@ -184,7 +183,7 @@ class UserSession {
. ' VALUES (:user, INET6_ATON(:remote_addr), :country, :user_agent, :token, NOW(), NOW() + INTERVAL :expires SECOND)'
) ->bind('user', $user->getId())
->bind('remote_addr', $remoteAddr)
->bind('country', IPAddress::country($remoteAddr))
->bind('country', $countryCode)
->bind('user_agent', $userAgent)
->bind('token', $token)
->bind('expires', self::LIFETIME)