[backend/federation] Respect UserSettings.AutoAcceptFollowed
This commit is contained in:
parent
d3deeb4bf2
commit
8f508d0c72
1 changed files with 81 additions and 16 deletions
|
@ -649,6 +649,7 @@ public class UserService(
|
||||||
|
|
||||||
Guid? relationshipId = null;
|
Guid? relationshipId = null;
|
||||||
|
|
||||||
|
// If followee is remote, send a follow activity immediately
|
||||||
if (followee.IsRemoteUser)
|
if (followee.IsRemoteUser)
|
||||||
{
|
{
|
||||||
relationshipId = Guid.NewGuid();
|
relationshipId = Guid.NewGuid();
|
||||||
|
@ -656,12 +657,12 @@ public class UserService(
|
||||||
await deliverSvc.DeliverToAsync(activity, follower, followee);
|
await deliverSvc.DeliverToAsync(activity, follower, followee);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check blocks separately for local/remote follower
|
||||||
if (follower.IsRemoteUser)
|
if (follower.IsRemoteUser)
|
||||||
{
|
{
|
||||||
if (requestId == null)
|
if (requestId == null)
|
||||||
throw GracefulException.UnprocessableEntity("Cannot process remote follow without requestId");
|
throw GracefulException.UnprocessableEntity("Cannot process remote follow without requestId");
|
||||||
|
|
||||||
// Check blocks first
|
|
||||||
if (await db.Users.AnyAsync(p => p == followee && p.IsBlocking(follower)))
|
if (await db.Users.AnyAsync(p => p == followee && p.IsBlocking(follower)))
|
||||||
{
|
{
|
||||||
var activity = activityRenderer.RenderReject(followee, follower, requestId);
|
var activity = activityRenderer.RenderReject(followee, follower, requestId);
|
||||||
|
@ -675,12 +676,86 @@ public class UserService(
|
||||||
throw GracefulException.UnprocessableEntity("You are not allowed to follow this user");
|
throw GracefulException.UnprocessableEntity("You are not allowed to follow this user");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We have to create a request instead of a follow relationship in these cases
|
||||||
if (followee.IsLocked || followee.IsRemoteUser)
|
if (followee.IsLocked || followee.IsRemoteUser)
|
||||||
{
|
{
|
||||||
if (!await db.FollowRequests.AnyAsync(p => p.Follower == follower && p.Followee == followee))
|
// We already have a pending follow request, so we want to update the request id in case it changed
|
||||||
|
if (await db.FollowRequests.AnyAsync(p => p.Follower == follower && p.Followee == followee))
|
||||||
{
|
{
|
||||||
if (!await db.Followings.AnyAsync(p => p.Follower == follower && p.Followee == followee))
|
await db.FollowRequests.Where(p => p.Follower == follower && p.Followee == followee)
|
||||||
|
.ExecuteUpdateAsync(p => p.SetProperty(i => i.RequestId, _ => requestId));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// There already is an established follow relationship
|
||||||
|
if (await db.Followings.AnyAsync(p => p.Follower == follower && p.Followee == followee))
|
||||||
{
|
{
|
||||||
|
// If the follower is remote, immediately send an accept activity, otherwise do nothing
|
||||||
|
if (follower.IsRemoteUser)
|
||||||
|
{
|
||||||
|
if (requestId == null)
|
||||||
|
throw new Exception("requestId must not be null at this stage");
|
||||||
|
|
||||||
|
var activity = activityRenderer.RenderAccept(followee, follower, requestId);
|
||||||
|
await deliverSvc.DeliverToAsync(activity, followee, follower);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Otherwise, create a new request and insert it into the database
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var autoAccept = followee.IsLocalUser &&
|
||||||
|
await db.Followings.AnyAsync(p => p.Follower == followee &&
|
||||||
|
p.Followee == follower &&
|
||||||
|
p.Follower.UserSettings != null &&
|
||||||
|
p.Follower.UserSettings.AutoAcceptFollowed);
|
||||||
|
|
||||||
|
// Followee has auto accept enabled & is already following the follower user
|
||||||
|
if (autoAccept)
|
||||||
|
{
|
||||||
|
if (requestId == null)
|
||||||
|
throw new Exception("requestId must not be null at this stage");
|
||||||
|
|
||||||
|
var activity = activityRenderer.RenderAccept(followee, follower, requestId);
|
||||||
|
await deliverSvc.DeliverToAsync(activity, followee, follower);
|
||||||
|
|
||||||
|
var following = new Following
|
||||||
|
{
|
||||||
|
Id = IdHelpers.GenerateSlowflakeId(),
|
||||||
|
CreatedAt = DateTime.UtcNow,
|
||||||
|
Followee = followee,
|
||||||
|
Follower = follower,
|
||||||
|
FolloweeHost = followee.Host,
|
||||||
|
FollowerHost = follower.Host,
|
||||||
|
FolloweeInbox = followee.Inbox,
|
||||||
|
FollowerInbox = follower.Inbox,
|
||||||
|
FolloweeSharedInbox = followee.SharedInbox,
|
||||||
|
FollowerSharedInbox = follower.SharedInbox
|
||||||
|
};
|
||||||
|
|
||||||
|
await db.AddAsync(following);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
await notificationSvc.GenerateFollowNotification(follower, followee);
|
||||||
|
|
||||||
|
await db.Users.Where(p => p.Id == follower.Id)
|
||||||
|
.ExecuteUpdateAsync(p => p.SetProperty(i => i.FollowingCount,
|
||||||
|
i => i.FollowingCount + 1));
|
||||||
|
await db.Users.Where(p => p.Id == followee.Id)
|
||||||
|
.ExecuteUpdateAsync(p => p.SetProperty(i => i.FollowersCount,
|
||||||
|
i => i.FollowersCount + 1));
|
||||||
|
|
||||||
|
_ = followupTaskSvc.ExecuteTask("IncrementInstanceIncomingFollowsCounter", async provider =>
|
||||||
|
{
|
||||||
|
var bgDb = provider.GetRequiredService<DatabaseContext>();
|
||||||
|
var bgInstanceSvc = provider.GetRequiredService<InstanceService>();
|
||||||
|
var dbInstance = await bgInstanceSvc.GetUpdatedInstanceMetadataAsync(follower);
|
||||||
|
await bgDb.Instances.Where(p => p.Id == dbInstance.Id)
|
||||||
|
.ExecuteUpdateAsync(p => p.SetProperty(i => i.IncomingFollows,
|
||||||
|
i => i.IncomingFollows + 1));
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var request = new FollowRequest
|
var request = new FollowRequest
|
||||||
{
|
{
|
||||||
Id = IdHelpers.GenerateSlowflakeId(),
|
Id = IdHelpers.GenerateSlowflakeId(),
|
||||||
|
@ -701,23 +776,12 @@ public class UserService(
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
await notificationSvc.GenerateFollowRequestReceivedNotification(request);
|
await notificationSvc.GenerateFollowRequestReceivedNotification(request);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (requestId == null)
|
|
||||||
throw new Exception("requestId must not be null at this stage");
|
|
||||||
|
|
||||||
var activity = activityRenderer.RenderAccept(followee, follower, requestId);
|
|
||||||
await deliverSvc.DeliverToAsync(activity, followee, follower);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await db.FollowRequests.Where(p => p.Follower == follower && p.Followee == followee)
|
|
||||||
.ExecuteUpdateAsync(p => p.SetProperty(i => i.RequestId, _ => requestId));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Followee is local and not locked
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// If there isn't an established follow relationship already, create one
|
||||||
if (!await db.Followings.AnyAsync(p => p.Follower == follower && p.Followee == followee))
|
if (!await db.Followings.AnyAsync(p => p.Follower == follower && p.Followee == followee))
|
||||||
{
|
{
|
||||||
var following = new Following
|
var following = new Following
|
||||||
|
@ -754,6 +818,7 @@ public class UserService(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If follower is remote, send an accept activity
|
||||||
if (follower.IsRemoteUser)
|
if (follower.IsRemoteUser)
|
||||||
{
|
{
|
||||||
if (requestId == null)
|
if (requestId == null)
|
||||||
|
|
Loading…
Add table
Reference in a new issue