added Delete logic
This commit is contained in:
parent
93b43ee4a0
commit
7205a09eaa
6 changed files with 199 additions and 69 deletions
|
@ -0,0 +1,51 @@
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BirdsiteLive.DAL.Contracts;
|
||||||
|
using BirdsiteLive.DAL.Models;
|
||||||
|
|
||||||
|
namespace BirdsiteLive.Domain.BusinessUseCases
|
||||||
|
{
|
||||||
|
public interface IProcessDeleteUser
|
||||||
|
{
|
||||||
|
Task ExecuteAsync(Follower follower);
|
||||||
|
Task ExecuteAsync(string followerUsername, string followerDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ProcessDeleteUser : IProcessDeleteUser
|
||||||
|
{
|
||||||
|
private readonly IFollowersDal _followersDal;
|
||||||
|
private readonly ITwitterUserDal _twitterUserDal;
|
||||||
|
|
||||||
|
#region Ctor
|
||||||
|
public ProcessDeleteUser(IFollowersDal followersDal, ITwitterUserDal twitterUserDal)
|
||||||
|
{
|
||||||
|
_followersDal = followersDal;
|
||||||
|
_twitterUserDal = twitterUserDal;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public async Task ExecuteAsync(string followerUsername, string followerDomain)
|
||||||
|
{
|
||||||
|
// Get Follower and Twitter Users
|
||||||
|
var follower = await _followersDal.GetFollowerAsync(followerUsername, followerDomain);
|
||||||
|
if (follower == null) return;
|
||||||
|
|
||||||
|
await ExecuteAsync(follower);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ExecuteAsync(Follower follower)
|
||||||
|
{
|
||||||
|
// Remove twitter users if no more followers
|
||||||
|
var followings = follower.Followings;
|
||||||
|
foreach (var following in followings)
|
||||||
|
{
|
||||||
|
var followers = await _followersDal.GetFollowersAsync(following);
|
||||||
|
if (followers.Length == 1 && followers.First().Id == follower.Id)
|
||||||
|
await _twitterUserDal.DeleteTwitterUserAsync(following);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove follower from DB
|
||||||
|
await _followersDal.DeleteFollowerAsync(follower.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace BirdsiteLive.Domain.Tools
|
||||||
|
{
|
||||||
|
public class SigValidationResultExtractor
|
||||||
|
{
|
||||||
|
public static string GetUserName(SignatureValidationResult result)
|
||||||
|
{
|
||||||
|
return result.User.preferredUsername.ToLowerInvariant().Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetHost(SignatureValidationResult result)
|
||||||
|
{
|
||||||
|
return result.User.url.Replace("https://", string.Empty).Split('/').First();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetSharedInbox(SignatureValidationResult result)
|
||||||
|
{
|
||||||
|
return result.User?.endpoints?.sharedInbox;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ namespace BirdsiteLive.Domain
|
||||||
|
|
||||||
public class UserService : IUserService
|
public class UserService : IUserService
|
||||||
{
|
{
|
||||||
|
private readonly IProcessDeleteUser _processDeleteUser;
|
||||||
private readonly IProcessFollowUser _processFollowUser;
|
private readonly IProcessFollowUser _processFollowUser;
|
||||||
private readonly IProcessUndoFollowUser _processUndoFollowUser;
|
private readonly IProcessUndoFollowUser _processUndoFollowUser;
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ namespace BirdsiteLive.Domain
|
||||||
private readonly IModerationRepository _moderationRepository;
|
private readonly IModerationRepository _moderationRepository;
|
||||||
|
|
||||||
#region Ctor
|
#region Ctor
|
||||||
public UserService(InstanceSettings instanceSettings, ICryptoService cryptoService, IActivityPubService activityPubService, IProcessFollowUser processFollowUser, IProcessUndoFollowUser processUndoFollowUser, IStatusExtractor statusExtractor, IExtractionStatisticsHandler statisticsHandler, ITwitterUserService twitterUserService, IModerationRepository moderationRepository)
|
public UserService(InstanceSettings instanceSettings, ICryptoService cryptoService, IActivityPubService activityPubService, IProcessFollowUser processFollowUser, IProcessUndoFollowUser processUndoFollowUser, IStatusExtractor statusExtractor, IExtractionStatisticsHandler statisticsHandler, ITwitterUserService twitterUserService, IModerationRepository moderationRepository, IProcessDeleteUser processDeleteUser)
|
||||||
{
|
{
|
||||||
_instanceSettings = instanceSettings;
|
_instanceSettings = instanceSettings;
|
||||||
_cryptoService = cryptoService;
|
_cryptoService = cryptoService;
|
||||||
|
@ -59,6 +60,7 @@ namespace BirdsiteLive.Domain
|
||||||
_statisticsHandler = statisticsHandler;
|
_statisticsHandler = statisticsHandler;
|
||||||
_twitterUserService = twitterUserService;
|
_twitterUserService = twitterUserService;
|
||||||
_moderationRepository = moderationRepository;
|
_moderationRepository = moderationRepository;
|
||||||
|
_processDeleteUser = processDeleteUser;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -128,10 +130,10 @@ namespace BirdsiteLive.Domain
|
||||||
if (!sigValidation.SignatureIsValidated) return false;
|
if (!sigValidation.SignatureIsValidated) return false;
|
||||||
|
|
||||||
// Prepare data
|
// Prepare data
|
||||||
var followerUserName = sigValidation.User.preferredUsername.ToLowerInvariant().Trim();
|
var followerUserName = SigValidationResultExtractor.GetUserName(sigValidation);
|
||||||
var followerHost = sigValidation.User.url.Replace("https://", string.Empty).Split('/').First();
|
var followerHost = SigValidationResultExtractor.GetHost(sigValidation);
|
||||||
var followerInbox = sigValidation.User.inbox;
|
var followerInbox = sigValidation.User.inbox;
|
||||||
var followerSharedInbox = sigValidation.User?.endpoints?.sharedInbox;
|
var followerSharedInbox = SigValidationResultExtractor.GetSharedInbox(sigValidation);
|
||||||
var twitterUser = activity.apObject.Split('/').Last().Replace("@", string.Empty).ToLowerInvariant().Trim();
|
var twitterUser = activity.apObject.Split('/').Last().Replace("@", string.Empty).ToLowerInvariant().Trim();
|
||||||
|
|
||||||
// Make sure to only keep routes
|
// Make sure to only keep routes
|
||||||
|
@ -268,7 +270,10 @@ namespace BirdsiteLive.Domain
|
||||||
if (!sigValidation.SignatureIsValidated) return false;
|
if (!sigValidation.SignatureIsValidated) return false;
|
||||||
|
|
||||||
// Remove user and followings
|
// Remove user and followings
|
||||||
throw new NotImplementedException();
|
var followerUserName = SigValidationResultExtractor.GetUserName(sigValidation);
|
||||||
|
var followerHost = SigValidationResultExtractor.GetHost(sigValidation);
|
||||||
|
|
||||||
|
await _processDeleteUser.ExecuteAsync(followerUserName, followerHost);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
using System;
|
using System.Threading.Tasks;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using BirdsiteLive.ActivityPub;
|
|
||||||
using BirdsiteLive.ActivityPub.Converters;
|
|
||||||
using BirdsiteLive.Common.Settings;
|
|
||||||
using BirdsiteLive.DAL.Contracts;
|
|
||||||
using BirdsiteLive.DAL.Models;
|
using BirdsiteLive.DAL.Models;
|
||||||
using BirdsiteLive.Domain;
|
using BirdsiteLive.Domain.BusinessUseCases;
|
||||||
|
|
||||||
namespace BirdsiteLive.Moderation.Actions
|
namespace BirdsiteLive.Moderation.Actions
|
||||||
{
|
{
|
||||||
|
@ -17,16 +11,14 @@ namespace BirdsiteLive.Moderation.Actions
|
||||||
|
|
||||||
public class RemoveFollowerAction : IRemoveFollowerAction
|
public class RemoveFollowerAction : IRemoveFollowerAction
|
||||||
{
|
{
|
||||||
private readonly IFollowersDal _followersDal;
|
|
||||||
private readonly ITwitterUserDal _twitterUserDal;
|
|
||||||
private readonly IRejectAllFollowingsAction _rejectAllFollowingsAction;
|
private readonly IRejectAllFollowingsAction _rejectAllFollowingsAction;
|
||||||
|
private readonly IProcessDeleteUser _processDeleteUser;
|
||||||
|
|
||||||
#region Ctor
|
#region Ctor
|
||||||
public RemoveFollowerAction(IFollowersDal followersDal, ITwitterUserDal twitterUserDal, IRejectAllFollowingsAction rejectAllFollowingsAction)
|
public RemoveFollowerAction(IRejectAllFollowingsAction rejectAllFollowingsAction, IProcessDeleteUser processDeleteUser)
|
||||||
{
|
{
|
||||||
_followersDal = followersDal;
|
|
||||||
_twitterUserDal = twitterUserDal;
|
|
||||||
_rejectAllFollowingsAction = rejectAllFollowingsAction;
|
_rejectAllFollowingsAction = rejectAllFollowingsAction;
|
||||||
|
_processDeleteUser = processDeleteUser;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -36,16 +28,7 @@ namespace BirdsiteLive.Moderation.Actions
|
||||||
await _rejectAllFollowingsAction.ProcessAsync(follower);
|
await _rejectAllFollowingsAction.ProcessAsync(follower);
|
||||||
|
|
||||||
// Remove twitter users if no more followers
|
// Remove twitter users if no more followers
|
||||||
var followings = follower.Followings;
|
await _processDeleteUser.ExecuteAsync(follower);
|
||||||
foreach (var following in followings)
|
|
||||||
{
|
|
||||||
var followers = await _followersDal.GetFollowersAsync(following);
|
|
||||||
if (followers.Length == 1 && followers.First().Id == follower.Id)
|
|
||||||
await _twitterUserDal.DeleteTwitterUserAsync(following);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove follower from DB
|
|
||||||
await _followersDal.DeleteFollowerAsync(follower.Id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BirdsiteLive.DAL.Contracts;
|
||||||
|
using BirdsiteLive.DAL.Models;
|
||||||
|
using BirdsiteLive.Domain.BusinessUseCases;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Moq;
|
||||||
|
|
||||||
|
namespace BirdsiteLive.Domain.Tests.BusinessUseCases
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class ProcessDeleteUserTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_NoMoreFollowings()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var follower = new Follower
|
||||||
|
{
|
||||||
|
Id = 12,
|
||||||
|
Followings = new List<int> { 1 }
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.GetFollowersAsync(
|
||||||
|
It.Is<int>(y => y == 1)))
|
||||||
|
.ReturnsAsync(new[] { follower });
|
||||||
|
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.DeleteFollowerAsync(
|
||||||
|
It.Is<int>(y => y == 12)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
|
||||||
|
twitterUserDalMock
|
||||||
|
.Setup(x => x.DeleteTwitterUserAsync(
|
||||||
|
It.Is<int>(y => y == 1)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var action = new ProcessDeleteUser(followersDalMock.Object, twitterUserDalMock.Object);
|
||||||
|
await action.ExecuteAsync(follower);
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
twitterUserDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ExecuteAsync_HaveFollowings()
|
||||||
|
{
|
||||||
|
#region Stubs
|
||||||
|
var follower = new Follower
|
||||||
|
{
|
||||||
|
Id = 12,
|
||||||
|
Followings = new List<int> { 1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
var followers = new List<Follower>
|
||||||
|
{
|
||||||
|
follower,
|
||||||
|
new Follower
|
||||||
|
{
|
||||||
|
Id = 11
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mocks
|
||||||
|
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.GetFollowersAsync(
|
||||||
|
It.Is<int>(y => y == 1)))
|
||||||
|
.ReturnsAsync(followers.ToArray());
|
||||||
|
|
||||||
|
followersDalMock
|
||||||
|
.Setup(x => x.DeleteFollowerAsync(
|
||||||
|
It.Is<int>(y => y == 12)))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var action = new ProcessDeleteUser(followersDalMock.Object, twitterUserDalMock.Object);
|
||||||
|
await action.ExecuteAsync(follower);
|
||||||
|
|
||||||
|
#region Validations
|
||||||
|
followersDalMock.VerifyAll();
|
||||||
|
twitterUserDalMock.VerifyAll();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BirdsiteLive.DAL.Contracts;
|
using BirdsiteLive.DAL.Contracts;
|
||||||
using BirdsiteLive.DAL.Models;
|
using BirdsiteLive.DAL.Models;
|
||||||
|
using BirdsiteLive.Domain.BusinessUseCases;
|
||||||
using BirdsiteLive.Moderation.Actions;
|
using BirdsiteLive.Moderation.Actions;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
@ -29,31 +30,19 @@ namespace BirdsiteLive.Moderation.Tests.Actions
|
||||||
It.Is<Follower>(y => y.Id == follower.Id)))
|
It.Is<Follower>(y => y.Id == follower.Id)))
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
var processDeleteUserMock = new Mock<IProcessDeleteUser>(MockBehavior.Strict);
|
||||||
followersDalMock
|
processDeleteUserMock
|
||||||
.Setup(x => x.GetFollowersAsync(
|
.Setup(x => x.ExecuteAsync(
|
||||||
It.Is<int>(y => y == 1)))
|
It.Is<Follower>(y => y.Id == follower.Id)))
|
||||||
.ReturnsAsync(new[] {follower});
|
|
||||||
|
|
||||||
followersDalMock
|
|
||||||
.Setup(x => x.DeleteFollowerAsync(
|
|
||||||
It.Is<int>(y => y == 12)))
|
|
||||||
.Returns(Task.CompletedTask);
|
|
||||||
|
|
||||||
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
|
|
||||||
twitterUserDalMock
|
|
||||||
.Setup(x => x.DeleteTwitterUserAsync(
|
|
||||||
It.Is<int>(y => y == 1)))
|
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
var action = new RemoveFollowerAction(followersDalMock.Object, twitterUserDalMock.Object, rejectAllFollowingsActionMock.Object);
|
var action = new RemoveFollowerAction(rejectAllFollowingsActionMock.Object, processDeleteUserMock.Object);
|
||||||
await action.ProcessAsync(follower);
|
await action.ProcessAsync(follower);
|
||||||
|
|
||||||
#region Validations
|
#region Validations
|
||||||
followersDalMock.VerifyAll();
|
|
||||||
twitterUserDalMock.VerifyAll();
|
|
||||||
rejectAllFollowingsActionMock.VerifyAll();
|
rejectAllFollowingsActionMock.VerifyAll();
|
||||||
|
processDeleteUserMock.VerifyAll();
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,15 +55,6 @@ namespace BirdsiteLive.Moderation.Tests.Actions
|
||||||
Id = 12,
|
Id = 12,
|
||||||
Followings = new List<int> { 1 }
|
Followings = new List<int> { 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
var followers = new List<Follower>
|
|
||||||
{
|
|
||||||
follower,
|
|
||||||
new Follower
|
|
||||||
{
|
|
||||||
Id = 11
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Mocks
|
#region Mocks
|
||||||
|
@ -84,27 +64,19 @@ namespace BirdsiteLive.Moderation.Tests.Actions
|
||||||
It.Is<Follower>(y => y.Id == follower.Id)))
|
It.Is<Follower>(y => y.Id == follower.Id)))
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var followersDalMock = new Mock<IFollowersDal>(MockBehavior.Strict);
|
var processDeleteUserMock = new Mock<IProcessDeleteUser>(MockBehavior.Strict);
|
||||||
followersDalMock
|
processDeleteUserMock
|
||||||
.Setup(x => x.GetFollowersAsync(
|
.Setup(x => x.ExecuteAsync(
|
||||||
It.Is<int>(y => y == 1)))
|
It.Is<Follower>(y => y.Id == follower.Id)))
|
||||||
.ReturnsAsync(followers.ToArray());
|
|
||||||
|
|
||||||
followersDalMock
|
|
||||||
.Setup(x => x.DeleteFollowerAsync(
|
|
||||||
It.Is<int>(y => y == 12)))
|
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
var twitterUserDalMock = new Mock<ITwitterUserDal>(MockBehavior.Strict);
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
var action = new RemoveFollowerAction(followersDalMock.Object, twitterUserDalMock.Object, rejectAllFollowingsActionMock.Object);
|
var action = new RemoveFollowerAction(rejectAllFollowingsActionMock.Object, processDeleteUserMock.Object);
|
||||||
await action.ProcessAsync(follower);
|
await action.ProcessAsync(follower);
|
||||||
|
|
||||||
#region Validations
|
#region Validations
|
||||||
followersDalMock.VerifyAll();
|
|
||||||
twitterUserDalMock.VerifyAll();
|
|
||||||
rejectAllFollowingsActionMock.VerifyAll();
|
rejectAllFollowingsActionMock.VerifyAll();
|
||||||
|
processDeleteUserMock.VerifyAll();
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue