From eef2adf12aae7c79f1eb525df67b18b234902961 Mon Sep 17 00:00:00 2001
From: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com>
Date: Thu, 8 Aug 2024 22:07:41 -0500
Subject: [PATCH 01/15] allows admins to view user ips for easy blocking
---
migrations/Version20240808230919.php | 29 ++++++++++++++++++++++++++++
src/Entity/User.php | 2 ++
src/Security/GithubAuthenticator.php | 3 +++
src/Security/UserChecker.php | 9 ++++++++-
src/Service/EntryCommentManager.php | 4 ++++
src/Service/EntryManager.php | 8 ++++++++
src/Service/PostCommentManager.php | 4 ++++
src/Service/PostManager.php | 8 ++++++++
templates/admin/users.html.twig | 6 ++++++
9 files changed, 72 insertions(+), 1 deletion(-)
create mode 100644 migrations/Version20240808230919.php
diff --git a/migrations/Version20240808230919.php b/migrations/Version20240808230919.php
new file mode 100644
index 000000000..c360f952a
--- /dev/null
+++ b/migrations/Version20240808230919.php
@@ -0,0 +1,29 @@
+addSql('ALTER TABLE "user" ADD ip VARCHAR(255) DEFAULT NULL');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('ALTER TABLE "user" DROP ip');
+ }
+}
diff --git a/src/Entity/User.php b/src/Entity/User.php
index dcf2d5af9..51e983fc7 100644
--- a/src/Entity/User.php
+++ b/src/Entity/User.php
@@ -93,6 +93,8 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface, Visibil
public ?Image $cover = null;
#[Column(type: 'string', unique: true, nullable: false)]
public string $email;
+ #[Column(type: 'string', nullable: true)]
+ public ?string $ip = null;
#[Column(type: 'string', unique: true, nullable: false)]
public string $username;
#[Column(type: 'json', nullable: false, options: ['jsonb' => true])]
diff --git a/src/Security/GithubAuthenticator.php b/src/Security/GithubAuthenticator.php
index 476fd6c18..97f5e60c0 100644
--- a/src/Security/GithubAuthenticator.php
+++ b/src/Security/GithubAuthenticator.php
@@ -6,6 +6,7 @@
use App\DTO\UserDto;
use App\Entity\User;
+use App\Service\IpResolver;
use App\Service\SettingsManager;
use App\Service\UserManager;
use App\Utils\Slugger;
@@ -31,6 +32,7 @@ public function __construct(
private readonly RouterInterface $router,
private readonly EntityManagerInterface $entityManager,
private readonly UserManager $userManager,
+ private readonly IpResolver $ipResolver,
private readonly Slugger $slugger,
private readonly SettingsManager $settingsManager
) {
@@ -84,6 +86,7 @@ public function authenticate(Request $request): Passport
);
$dto->plainPassword = bin2hex(random_bytes(20));
+ $dto->ip = $this->ipResolver->resolve();
$user = $this->userManager->create($dto, false);
$user->oauthGithubId = \strval($githubUser->getId());
diff --git a/src/Security/UserChecker.php b/src/Security/UserChecker.php
index f265ff910..040848dd9 100644
--- a/src/Security/UserChecker.php
+++ b/src/Security/UserChecker.php
@@ -5,6 +5,8 @@
namespace App\Security;
use App\Entity\User as AppUser;
+use App\Service\IpResolver;
+use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException;
@@ -16,7 +18,9 @@ class UserChecker implements UserCheckerInterface
{
public function __construct(
private readonly TranslatorInterface $translator,
- private readonly UrlGeneratorInterface $urlGenerator
+ private readonly UrlGeneratorInterface $urlGenerator,
+ private readonly EntityManagerInterface $entityManager,
+ private readonly IpResolver $ipResolver
) {
}
@@ -45,5 +49,8 @@ public function checkPostAuth(UserInterface $user): void
if (!$user instanceof AppUser) {
return;
}
+
+ $user->ip = $this->ipResolver->resolve();
+ $this->entityManager->flush();
}
}
diff --git a/src/Service/EntryCommentManager.php b/src/Service/EntryCommentManager.php
index adaa6a4ed..7a75e6664 100644
--- a/src/Service/EntryCommentManager.php
+++ b/src/Service/EntryCommentManager.php
@@ -48,6 +48,10 @@ public function __construct(
public function create(EntryCommentDto $dto, User $user, $rateLimit = true): EntryComment
{
+ if (!$user->apId) {
+ $user->ip = $dto->ip;
+ }
+
if ($rateLimit) {
$limiter = $this->entryCommentLimiter->create($dto->ip);
if ($limiter && false === $limiter->consume()->isAccepted()) {
diff --git a/src/Service/EntryManager.php b/src/Service/EntryManager.php
index 0d600a1f9..c3cba3e7a 100644
--- a/src/Service/EntryManager.php
+++ b/src/Service/EntryManager.php
@@ -75,6 +75,10 @@ public function __construct(
*/
public function create(EntryDto $dto, User $user, bool $rateLimit = true, bool $stickyIt = false): Entry
{
+ if (!$user->apId) {
+ $user->ip = $dto->ip;
+ }
+
if ($rateLimit) {
$limiter = $this->entryLimiter->create($dto->ip);
if (false === $limiter->consume()->isAccepted()) {
@@ -182,6 +186,10 @@ public function canUserEditEntry(Entry $entry, User $user): bool
public function edit(Entry $entry, EntryDto $dto, User $editedBy): Entry
{
+ if (!$editedBy->apId) {
+ $editedBy->ip = $dto->ip;
+ }
+
Assert::same($entry->magazine->getId(), $dto->magazine->getId());
$entry->title = $dto->title;
diff --git a/src/Service/PostCommentManager.php b/src/Service/PostCommentManager.php
index 2b57336fb..2c9f9b6f5 100644
--- a/src/Service/PostCommentManager.php
+++ b/src/Service/PostCommentManager.php
@@ -54,6 +54,10 @@ public function __construct(
*/
public function create(PostCommentDto $dto, User $user, $rateLimit = true): PostComment
{
+ if (!$user->apId) {
+ $user->ip = $dto->ip;
+ }
+
if ($rateLimit) {
$limiter = $this->postCommentLimiter->create($dto->ip);
if ($limiter && false === $limiter->consume()->isAccepted()) {
diff --git a/src/Service/PostManager.php b/src/Service/PostManager.php
index 9e3b7dccf..1c9464ddc 100644
--- a/src/Service/PostManager.php
+++ b/src/Service/PostManager.php
@@ -66,6 +66,10 @@ public function __construct(
*/
public function create(PostDto $dto, User $user, $rateLimit = true, bool $stickyIt = false): Post
{
+ if (!$user->apId) {
+ $user->ip = $dto->ip;
+ }
+
if ($rateLimit) {
$limiter = $this->postLimiter->create($dto->ip);
if ($limiter && false === $limiter->consume()->isAccepted()) {
@@ -133,6 +137,10 @@ public function canUserEditPost(Post $post, User $user): bool
public function edit(Post $post, PostDto $dto, ?User $editedBy = null): Post
{
+ if (null !== $editedBy && !$editedBy->apId) {
+ $editedBy->ip = $dto->ip;
+ }
+
Assert::same($post->magazine->getId(), $dto->magazine->getId());
$post->body = $dto->body;
diff --git a/templates/admin/users.html.twig b/templates/admin/users.html.twig
index 9949452bd..8a8cb62ad 100644
--- a/templates/admin/users.html.twig
+++ b/templates/admin/users.html.twig
@@ -71,6 +71,9 @@
{{ 'username'|trans }} |
{{ 'email'|trans }} |
+ {% if withFederated is not defined or withFederated is same as false %}
+ {{ 'IP' }} |
+ {% endif %}
{{ 'created_at'|trans }} |
{{ 'last_active'|trans }} |
@@ -80,6 +83,9 @@
{{ component('user_inline', {user: user}) }} |
{{ user.apId ? '-' : user.email }} |
+ {% if withFederated is not defined or withFederated is same as false %}
+ {{ user.ip }} |
+ {% endif %}
{{ component('date', {date: user.createdAt}) }} |
{{ component('date', {date: user.lastActive}) }} |
From 28ace2aa7c5c991d8ab3bdea537aeffe743ac3a1 Mon Sep 17 00:00:00 2001
From: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com>
Date: Thu, 8 Aug 2024 22:22:59 -0500
Subject: [PATCH 02/15] fix lint
---
src/Service/EntryCommentManager.php | 2 +-
src/Service/PostCommentManager.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Service/EntryCommentManager.php b/src/Service/EntryCommentManager.php
index 7a75e6664..78acc80c4 100644
--- a/src/Service/EntryCommentManager.php
+++ b/src/Service/EntryCommentManager.php
@@ -51,7 +51,7 @@ public function create(EntryCommentDto $dto, User $user, $rateLimit = true): Ent
if (!$user->apId) {
$user->ip = $dto->ip;
}
-
+
if ($rateLimit) {
$limiter = $this->entryCommentLimiter->create($dto->ip);
if ($limiter && false === $limiter->consume()->isAccepted()) {
diff --git a/src/Service/PostCommentManager.php b/src/Service/PostCommentManager.php
index 2c9f9b6f5..2f5e4f2e5 100644
--- a/src/Service/PostCommentManager.php
+++ b/src/Service/PostCommentManager.php
@@ -57,7 +57,7 @@ public function create(PostCommentDto $dto, User $user, $rateLimit = true): Post
if (!$user->apId) {
$user->ip = $dto->ip;
}
-
+
if ($rateLimit) {
$limiter = $this->postCommentLimiter->create($dto->ip);
if ($limiter && false === $limiter->consume()->isAccepted()) {
From 639fc2dba3ce2eae66e7840e527fdf10c7e2ffd4 Mon Sep 17 00:00:00 2001
From: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com>
Date: Fri, 9 Aug 2024 08:47:15 -0500
Subject: [PATCH 03/15] add trusted proxy config
---
.env.example | 5 +++++
.env.example_docker | 5 +++++
config/packages/framework.yaml | 2 ++
3 files changed, 12 insertions(+)
diff --git a/.env.example b/.env.example
index c76c6ccd8..1123cd94a 100644
--- a/.env.example
+++ b/.env.example
@@ -32,6 +32,11 @@ KBIN_HEADER_LOGO=false
KBIN_FEDERATION_PAGE_ENABLED=true
MBIN_DEFAULT_THEME=default
+# If you are running Mbin behind a reverse proxy be sure to adjust the proxy address/range below
+# to your server's IP address if it does not already fall within the private IP spaces specified.
+#TRUSTED_PROXIES=::1,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
+TRUSTED_PROXIES=
+
# Max image filesize (in bytes)
# This should be set to <= `upload_max_filesize` and `post_max_size` in the server's php.ini file
MAX_IMAGE_BYTES=6000000
diff --git a/.env.example_docker b/.env.example_docker
index 36f0b811b..0bd7cf320 100644
--- a/.env.example_docker
+++ b/.env.example_docker
@@ -32,6 +32,11 @@ KBIN_HEADER_LOGO=false
KBIN_FEDERATION_PAGE_ENABLED=true
MBIN_DEFAULT_THEME=default
+# If you are running Mbin behind a reverse proxy be sure to adjust the proxy address/range below
+# to your server's IP address if it does not already fall within the private IP spaces specified.
+#TRUSTED_PROXIES=::1,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
+TRUSTED_PROXIES=
+
# Max image filesize (in bytes)
# This should be set to <= `upload_max_filesize` and `post_max_size` in the server's php.ini file
MAX_IMAGE_BYTES=6000000
diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml
index 6a4cbd2b9..391606515 100644
--- a/config/packages/framework.yaml
+++ b/config/packages/framework.yaml
@@ -4,6 +4,8 @@ framework:
annotations: false #no longer supported
http_method_override: false
handle_all_throwables: true
+ trusted_proxies: '%env(string:default::TRUSTED_PROXIES)%'
+ trusted_headers: ['x-forwarded-for', 'x-forwarded-proto', 'x-forwarded-port', 'x-forwarded-prefix']
# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
From 72d0c85c57550260f216c08b966cfddd35ec4698 Mon Sep 17 00:00:00 2001
From: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com>
Date: Fri, 9 Aug 2024 08:53:46 -0500
Subject: [PATCH 04/15] adjust env comment wording
---
.env.example | 2 +-
.env.example_docker | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.env.example b/.env.example
index 1123cd94a..7aa3d6a92 100644
--- a/.env.example
+++ b/.env.example
@@ -32,7 +32,7 @@ KBIN_HEADER_LOGO=false
KBIN_FEDERATION_PAGE_ENABLED=true
MBIN_DEFAULT_THEME=default
-# If you are running Mbin behind a reverse proxy be sure to adjust the proxy address/range below
+# If you are running Mbin behind a reverse proxy, uncomment the line below and adjust the proxy address/range below
# to your server's IP address if it does not already fall within the private IP spaces specified.
#TRUSTED_PROXIES=::1,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
TRUSTED_PROXIES=
diff --git a/.env.example_docker b/.env.example_docker
index 0bd7cf320..8bb786abd 100644
--- a/.env.example_docker
+++ b/.env.example_docker
@@ -32,7 +32,7 @@ KBIN_HEADER_LOGO=false
KBIN_FEDERATION_PAGE_ENABLED=true
MBIN_DEFAULT_THEME=default
-# If you are running Mbin behind a reverse proxy be sure to adjust the proxy address/range below
+# If you are running Mbin behind a reverse proxy, uncomment the line below and adjust the proxy address/range below
# to your server's IP address if it does not already fall within the private IP spaces specified.
#TRUSTED_PROXIES=::1,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
TRUSTED_PROXIES=
From 0457d4d6a52ba732ad7b20af590a829f90e35396 Mon Sep 17 00:00:00 2001
From: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com>
Date: Fri, 9 Aug 2024 09:04:09 -0500
Subject: [PATCH 05/15] add comment edit ip updates
---
src/Service/EntryCommentManager.php | 4 ++++
src/Service/PostCommentManager.php | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/src/Service/EntryCommentManager.php b/src/Service/EntryCommentManager.php
index 78acc80c4..eaa5c9119 100644
--- a/src/Service/EntryCommentManager.php
+++ b/src/Service/EntryCommentManager.php
@@ -118,6 +118,10 @@ public function canUserEditComment(EntryComment $comment, User $user): bool
public function edit(EntryComment $comment, EntryCommentDto $dto, ?User $editedByUser = null): EntryComment
{
+ if (null !== $editedByUser && !$editedByUser->apId) {
+ $editedByUser->ip = $dto->ip;
+ }
+
Assert::same($comment->entry->getId(), $dto->entry->getId());
$comment->body = $dto->body;
diff --git a/src/Service/PostCommentManager.php b/src/Service/PostCommentManager.php
index 2f5e4f2e5..659c86118 100644
--- a/src/Service/PostCommentManager.php
+++ b/src/Service/PostCommentManager.php
@@ -126,6 +126,10 @@ public function canUserEditPostComment(PostComment $postComment, User $user): bo
*/
public function edit(PostComment $comment, PostCommentDto $dto, ?User $editedBy = null): PostComment
{
+ if (null !== $editedBy && !$editedBy->apId) {
+ $editedBy->ip = $dto->ip;
+ }
+
Assert::same($comment->post->getId(), $dto->post->getId());
$comment->body = $dto->body;
From 9c0791a1dee2e0cd418e6cedcaaaadadc560e08f Mon Sep 17 00:00:00 2001
From: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com>
Date: Fri, 9 Aug 2024 09:31:44 -0500
Subject: [PATCH 06/15] add missing ip resolve on entry and post comment edits
---
.../Entry/Comment/EntryCommentEditController.php | 3 +++
src/Controller/Post/PostEditController.php | 8 ++++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/Controller/Entry/Comment/EntryCommentEditController.php b/src/Controller/Entry/Comment/EntryCommentEditController.php
index 4d9c03763..82ecf17bf 100644
--- a/src/Controller/Entry/Comment/EntryCommentEditController.php
+++ b/src/Controller/Entry/Comment/EntryCommentEditController.php
@@ -13,6 +13,7 @@
use App\PageView\EntryCommentPageView;
use App\Repository\EntryCommentRepository;
use App\Service\EntryCommentManager;
+use App\Service\IpResolver;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -27,6 +28,7 @@ class EntryCommentEditController extends AbstractController
public function __construct(
private readonly EntryCommentManager $manager,
private readonly EntryCommentRepository $repository,
+ private readonly IpResolver $ipResolver
) {
}
@@ -44,6 +46,7 @@ public function __invoke(
$dto = $this->manager->createDto($comment);
$form = $this->getForm($dto, $comment);
+ $dto->ip = $this->ipResolver->resolve();
try {
// Could thrown an error on event handlers (eg. onPostSubmit if a user upload an incorrect image)
$form->handleRequest($request);
diff --git a/src/Controller/Post/PostEditController.php b/src/Controller/Post/PostEditController.php
index c4e627e5e..b920d0398 100644
--- a/src/Controller/Post/PostEditController.php
+++ b/src/Controller/Post/PostEditController.php
@@ -11,6 +11,7 @@
use App\PageView\PostCommentPageView;
use App\Repository\PostCommentRepository;
use App\Service\PostManager;
+use App\Service\IpResolver;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -20,8 +21,10 @@
class PostEditController extends AbstractController
{
- public function __construct(private readonly PostManager $manager)
- {
+ public function __construct(
+ private readonly PostManager $manager,
+ private readonly IpResolver $ipResolver
+ ) {
}
#[IsGranted('ROLE_USER')]
@@ -37,6 +40,7 @@ public function __invoke(
$dto = $this->manager->createDto($post);
$form = $this->createForm(PostType::class, $dto);
+ $dto->ip = $this->ipResolver->resolve();
try {
// Could thrown an error on event handlers (eg. onPostSubmit if a user upload an incorrect image)
$form->handleRequest($request);
From df027b3a205e4094c0126a7f0153ae14f85b2c69 Mon Sep 17 00:00:00 2001
From: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com>
Date: Fri, 9 Aug 2024 09:32:15 -0500
Subject: [PATCH 07/15] fix lint
---
src/Controller/Post/PostEditController.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Controller/Post/PostEditController.php b/src/Controller/Post/PostEditController.php
index b920d0398..fa0e3a2f7 100644
--- a/src/Controller/Post/PostEditController.php
+++ b/src/Controller/Post/PostEditController.php
@@ -10,8 +10,8 @@
use App\Form\PostType;
use App\PageView\PostCommentPageView;
use App\Repository\PostCommentRepository;
-use App\Service\PostManager;
use App\Service\IpResolver;
+use App\Service\PostManager;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
From 0de0856b9628c34627ae350056db23737600e6ec Mon Sep 17 00:00:00 2001
From: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com>
Date: Fri, 9 Aug 2024 11:05:57 -0500
Subject: [PATCH 08/15] add email and ip info to user page for admins
---
templates/user/_info.html.twig | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/templates/user/_info.html.twig b/templates/user/_info.html.twig
index d5d64430c..26a337b1d 100644
--- a/templates/user/_info.html.twig
+++ b/templates/user/_info.html.twig
@@ -23,6 +23,13 @@
{{ component('user_actions', {user: user}) }}
{% endif %}
+ {% set instance = get_instance_of_user(user) %}
+
+ {% if is_granted('ROLE_ADMIN') and instance is same as null %}
+ - {{ 'IP' }}: {{ user.ip }}
+ - {{ 'email'|trans }}: {{ user.email }}
+ {% endif %}
+
- {{ 'joined'|trans }}: {{ component('date', {date: user.createdAt}) }}
- {{ 'cake_day'|trans }}:
{{ user.createdAt|format_date('short', '', null, 'gregorian', mbin_lang()) }}
{% if app.user is defined and app.user is not null and app.user.admin() and user.apId is not null %}
@@ -31,7 +38,6 @@
{% endif %}
- {% set instance = get_instance_of_user(user) %}
{% if instance is not same as null %}
- {{ 'server_software'|trans }}:
{{ instance.software }}{% if instance.version is not same as null and app.user is defined and app.user is not null and app.user.admin() %} v{{ instance.version }}{% endif %}
{% endif %}
From 3721b56339723c4f3083040cb937e31986df2843 Mon Sep 17 00:00:00 2001
From: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com>
Date: Fri, 9 Aug 2024 11:09:09 -0500
Subject: [PATCH 09/15] user correct condition check.......
---
templates/user/_info.html.twig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/templates/user/_info.html.twig b/templates/user/_info.html.twig
index 26a337b1d..832509183 100644
--- a/templates/user/_info.html.twig
+++ b/templates/user/_info.html.twig
@@ -25,7 +25,7 @@
{% set instance = get_instance_of_user(user) %}
- {% if is_granted('ROLE_ADMIN') and instance is same as null %}
+ {% if app.user is defined and app.user is not null and app.user.admin() and user.apId is null %}
- {{ 'IP' }}: {{ user.ip }}
- {{ 'email'|trans }}: {{ user.email }}
{% endif %}
From b0db660c1f67e6b0765aea760679fec6d1022eef Mon Sep 17 00:00:00 2001
From: nobodyatroot <35878315+nobodyatroot@users.noreply.github.com>
Date: Fri, 9 Aug 2024 11:10:52 -0500
Subject: [PATCH 10/15] move instance check back to original location...
---
templates/user/_info.html.twig | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/templates/user/_info.html.twig b/templates/user/_info.html.twig
index 832509183..4afa8037f 100644
--- a/templates/user/_info.html.twig
+++ b/templates/user/_info.html.twig
@@ -23,8 +23,6 @@
{{ component('user_actions', {user: user}) }}
{% endif %}