-
-
Notifications
You must be signed in to change notification settings - Fork 916
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
Receive and store remote site bans (fixes #3399) #5515
Conversation
82693f5
to
858621a
Compare
06ca08c
to
11d69db
Compare
Some(site.instance_id), | ||
true, | ||
) | ||
.await?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is the main logic for receiving federated site bans.
4716839
to
da732c0
Compare
ADD COLUMN instance_id int NOT NULL REFERENCES instance ON UPDATE CASCADE ON DELETE CASCADE; | ||
|
||
-- insert existing bans into instance_actions table, assuming they were all banned from home instance | ||
INSERT INTO instance_actions (person_id, instance_id, received_ban, ban_expires) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've never federated instance bans before this, so I think it's safer to only ban them from our local instance, not their home instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bans are already federated if they were made on the user's home instance, eg:
https://lemmy.ml/u/[email protected]
https://lemmy.ml/modlog?page=1&actionType=All&userId=17706104
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also add rows for local instance bans also? Seems like we don't know where these bans actually took place then, so it might be safer to do both.
} else { | ||
Ok(()) | ||
} | ||
InstanceActions::check_ban(&mut context.pool(), person.id, person.instance_id).await?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should check both.
@@ -160,6 +161,10 @@ impl Post { | |||
update = update.filter(post::community_id.eq(for_community_id)); | |||
} | |||
|
|||
if let Some(for_instance_id) = for_instance_id { | |||
update = update.filter(post::instance_id.eq(for_instance_id)); | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
post.instance_id
is the instance where the community is hosted, right? Otherwise this would be wrong. Not entirely clear to me where this gets set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yikes, it looks like instance_id isn't being set (and its default 0!).
I'll make an issue to remove that column, because it should rely on the community's instance_id
anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
|
||
pub async fn read(pool: &mut DbPool<'_>, local_user_id: LocalUserId) -> Result<Self, Error> { | ||
pub async fn read(pool: &mut DbPool<'_>, local_user_id: LocalUserId) -> LemmyResult<Self> { | ||
let local_instance_id = SiteView::read_local(pool).await?.instance.id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd much prefer all these read_local
s were brought up a level. Instead make local_instance_id
a function param.
Lets try to keep view and schema functions to a single DB query whenever possible, and keep multiple reads at the API / APUB level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont like that idea because it makes all the callsites more verbose. These methods are called in many dozens of places so it would have to be passed everywhere, its much easier to read the instance id only a couple of times here. Anyway thanks to caching it doesnt perform a actual db read in most cases.
.optional()? | ||
.ok_or(LemmyErrorType::LocalSiteNotSetup)?, | ||
) | ||
static CACHE: CacheLock<SiteView> = LazyLock::new(build_cache); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove caching from LocalSite::read
, and replace every case of it with this one. Possibly even remove that function or make it non-public.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment here: #5515 (comment)
crates/db_views/src/utils.rs
Outdated
#[diesel::dsl::auto_type] | ||
pub fn person_with_instance_actions(local_instance_id: InstanceId) -> _ { | ||
person::table.inner_join( | ||
instance_actions::table.on( | ||
instance_actions::instance_id | ||
.eq(local_instance_id) | ||
.and(instance_actions::person_id.eq(person::id)), | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename this to local_instance_person_join
, and remove line 179.
Then do person::table.left_join(local_instance_person_join(local_instance_id))
Then its more flexible.
Also I think it should be a left join.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed to left join. This function is always used together with person::table
so may as well make the calling code simpler by including it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather any filtering / common join statements be independent of the table, and only include the .on
clause. Check out here for an example.
If I included the original search_combined
table in all those, it would've been impossible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright changed
api_tests/src/post.spec.ts
Outdated
@@ -499,9 +500,9 @@ test("Enforce site ban federation for local user", async () => { | |||
// alpha ban should be federated to beta | |||
let alphaUserOnBeta1 = await waitUntil( | |||
() => resolvePerson(beta, alphaUserActorId!), | |||
res => res.person?.person.banned ?? false, | |||
res => res.person?.instance_actions?.received_ban != null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is now failing, because PersonView
only returns the ban for the local instance, but not the ban from user's home instance. Not sure what we should do here, return two instance_action
fields for local instance and for user's home instance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, probably named local_instance_actions
and home_instance_actions
. This unfortunately is going to require aliasing similar to creator_community_actions
.
We need to do the same for every view that joins to the instance table: one for the person's home instance, and another for our local instance.
Grepping for every case of instance_actions
in db_views/structs should be enough.
Let me know if you want me to do this, as I went through this process recently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. One disadvantage is that home_instance_actions
is also included for local users, so there is the same data twice. Also need to update the js client to get tests passing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm realizing that the way I did instance_actions is a bit wrong, so I'll start working on a PR to correct it to this one.
In short, I'm currently only doing instance actions for my user. In reality, similar to creator_community_actions
, we need it for the creator of the content. So we need a total of three:
instance_actions
: for my own actions to the item's homecreator_local_instance_actions
: for creator to our local instancecreator_home_instance_actions
: for creator to item's home instance
static CACHE: CacheLock<LocalSite> = LazyLock::new(build_cache); | ||
Ok( | ||
CACHE | ||
.try_get_with((), async { | ||
let conn = &mut get_conn(pool).await?; | ||
local_site::table.first(conn).await | ||
}) | ||
.await?, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Im not sure that is right.
I suppose the last one is what you are talking about, so we need to add |
The main issue is that the current instance_actions are always using my user, as opposed to the item creator. But I agree we can merge this to main, since I'm already cleaning this up anyway. |
this was originally removed in LemmyNet#5546, but LemmyNet#5515 introduced a new usage of it. due to the order of PR merges this slipped through and broke the build on main. fixes LemmyNet#5561
Continued from #4571
Todo:
instance_actions
:received_ban
andban_expires
ban_nonlocal_user_from_local_communities()
, send ban activity for remote usersinstance_actions
mod_ban.instance_id
person.banned
column?