Permalink
Browse files

Merge pull request #582 from phillip-haydon/BanCommand

added Ban command with tests
  • Loading branch information...
2 parents 875bce6 + 158689f commit a2405d0897ab5f7113867912190549c9899601d8 @samandmoore samandmoore committed Aug 31, 2012
@@ -1956,6 +1956,206 @@ public void RoomCreatorCanKickOwners()
}
}
+
+ public class BanCommand
+ {
+ [Fact]
+ public void MissingUserNameThrows()
+ {
+ var repository = new InMemoryRepository();
+ var cache = new Mock<ICache>().Object;
+ var user = new ChatUser
+ {
+ Name = "dfowler",
+ Id = "1",
+ IsAdmin = true
+ };
+ repository.Add(user);
+ var room = new ChatRoom
+ {
+ Name = "room"
+ };
+ room.Users.Add(user);
+ room.Owners.Add(user);
+ user.Rooms.Add(room);
+ repository.Add(room);
+
+ var service = new ChatService(cache, repository, new Mock<ICryptoService>().Object);
+ var notificationService = new Mock<INotificationService>();
+ var commandManager = new CommandManager("clientid",
+ "1",
+ "room",
+ service,
+ repository,
+ cache,
+ notificationService.Object);
+
+ Assert.Throws<InvalidOperationException>(() => commandManager.TryHandleCommand("/ban"));
+ }
+
+ [Fact]
+ public void BannerIsNotAnAdminThrows()
+ {
+ var repository = new InMemoryRepository();
+ var cache = new Mock<ICache>().Object;
+ var user = new ChatUser
+ {
+ Name = "dfowler",
+ Id = "1"
+ };
+ var user2 = new ChatUser
+ {
+ Name = "dfowler2",
+ Id = "1"
+ };
+ repository.Add(user);
+ var room = new ChatRoom
+ {
+ Name = "room"
+ };
+ room.Users.Add(user);
+ room.Owners.Add(user);
+ room.Users.Add(user2);
+ room.Owners.Add(user2);
+ user.Rooms.Add(room);
+ user2.Rooms.Add(room);
+ repository.Add(room);
+
+ var service = new ChatService(cache, repository, new Mock<ICryptoService>().Object);
+ var notificationService = new Mock<INotificationService>();
+ var commandManager = new CommandManager("clientid",
+ "1",
+ "room",
+ service,
+ repository,
+ cache,
+ notificationService.Object);
+
+ var ex = Assert.Throws<InvalidOperationException>(() => commandManager.TryHandleCommand("/ban dfowler2"));
+
+ Assert.True(ex.Message == "You are not an admin.");
+ }
+
+ [Fact]
+ public void CannotBanUserIfNotExists()
+ {
+ var repository = new InMemoryRepository();
+ var cache = new Mock<ICache>().Object;
+ var user = new ChatUser
+ {
+ Name = "dfowler",
+ Id = "1",
+ IsAdmin = true
+ };
+ repository.Add(user);
+ var user2 = new ChatUser
+ {
+ Name = "dfowler2",
+ Id = "2"
+ };
+ repository.Add(user2);
+ var room = new ChatRoom
+ {
+ Name = "room"
+ };
+ room.Users.Add(user);
+ room.Users.Add(user2);
+ room.Owners.Add(user);
+ user.Rooms.Add(room);
+ user2.Rooms.Add(room);
+ repository.Add(room);
+
+ var service = new ChatService(cache, repository, new Mock<ICryptoService>().Object);
+ var notificationService = new Mock<INotificationService>();
+ var commandManager = new CommandManager("clientid",
+ "1",
+ "room",
+ service,
+ repository,
+ cache,
+ notificationService.Object);
+
+ Assert.Throws<InvalidOperationException>(() => commandManager.TryHandleCommand("/ban fowler3"));
+ }
+
+ [Fact]
+ public void AdminCannotBanAdmin()
+ {
+ var repository = new InMemoryRepository();
+ var cache = new Mock<ICache>().Object;
+ var user = new ChatUser
+ {
+ Name = "dfowler",
+ Id = "1",
+ IsAdmin = true
+ };
+ repository.Add(user);
+ var user2 = new ChatUser
+ {
+ Name = "dfowler2",
+ Id = "2",
+ IsAdmin = true
+ };
+ repository.Add(user2);
+ var room = new ChatRoom
+ {
+ Name = "room"
+ };
+ room.Users.Add(user);
+ room.Users.Add(user2);
+ room.Owners.Add(user);
+ user.Rooms.Add(room);
+ user2.Rooms.Add(room);
+ repository.Add(room);
+
+ var service = new ChatService(cache, repository, new Mock<ICryptoService>().Object);
+ var notificationService = new Mock<INotificationService>();
+ var commandManager = new CommandManager("clientid",
+ "1",
+ "room",
+ service,
+ repository,
+ cache,
+ notificationService.Object);
+
+ Assert.Throws<InvalidOperationException>(() => commandManager.TryHandleCommand("/ban dfowler2"));
+ }
+
+ [Fact]
+ public void CannotBanUrSelf()
+ {
+ var repository = new InMemoryRepository();
+ var cache = new Mock<ICache>().Object;
+ var user = new ChatUser
+ {
+ Name = "dfowler",
+ Id = "1",
+ IsAdmin = true
+ };
+ repository.Add(user);
+ var room = new ChatRoom
+ {
+ Name = "room"
+ };
+ room.Users.Add(user);
+ room.Owners.Add(user);
+ user.Rooms.Add(room);
+ repository.Add(room);
+
+ var service = new ChatService(cache, repository, new Mock<ICryptoService>().Object);
+ var notificationService = new Mock<INotificationService>();
+ var commandManager = new CommandManager("clientid",
+ "1",
+ "room",
+ service,
+ repository,
+ cache,
+ notificationService.Object);
+
+ Assert.Throws<InvalidOperationException>(() => commandManager.TryHandleCommand("/ban dfowler"));
+ }
+ }
+
public class LeaveCommand
{
[Fact]
@@ -109,6 +109,13 @@ public void ProcessRequest(HttpContext context)
repository.CommitChanges();
}
+ // IsBanned is set to false if the user is new
+ // but check is placed here so it doesn't need to be checked twice in above user-if-conditions
+ if (user.IsBanned)
+ {
+ throw new InvalidOperationException("You're banned, sorry.");
+ }
+
// Save the cokie state
var state = JsonConvert.SerializeObject(new { userId = user.Id });
var cookie = new HttpCookie("jabbr.state", state);
@@ -0,0 +1,27 @@
+using System;
+using System.Linq;
+using System.Web;
+using JabbR.Models;
+
+namespace JabbR.Commands
+{
+ [Command("ban", "Ban a user from JabbR!", "user", "admin")]
+ public class BanCommand : AdminCommand
+ {
+ public override void ExecuteAdminOperation(CommandContext context, CallerContext callerContext, ChatUser callingUser, string[] args)
+ {
+ if (args.Length == 0)
+ {
+ throw new InvalidOperationException("Who are you trying to ban?");
+ }
+
+ string targetUserName = HttpUtility.HtmlDecode(args[0]);
+
+ ChatUser targetUser = context.Repository.VerifyUser(targetUserName);
+
+ context.Service.BanUser(callingUser, targetUser);
+ context.NotificationService.BanUser(targetUser);
+ context.Repository.CommitChanges();
+ }
+ }
+}
@@ -51,6 +51,11 @@ public void Execute(CommandContext context, CallerContext callerContext, string[
}
else
{
+ if (user.IsBanned)
+ {
+ throw new InvalidOperationException("You're banned, sorry.");
+ }
+
// If there's no user but there's a password then authenticate the user
context.Service.AuthenticateUser(userName, password);
View
@@ -1023,5 +1023,24 @@ private string GetCookieValue(string key)
string value = cookie != null ? cookie.Value : null;
return value != null ? HttpUtility.UrlDecode(value) : null;
}
+
+ void INotificationService.BanUser(ChatUser targetUser)
+ {
+ var rooms = targetUser.Rooms.Select(x => x.Name);
+
+ foreach (var room in rooms)
+ {
+ foreach (var client in targetUser.ConnectedClients)
+ {
+ // Kick the user from this room
+ Clients[client.Id].kick(room);
+
+ // Remove the user from this the room group so he doesn't get the leave message
+ Groups.Remove(client.Id, room).Wait();
+ }
+ }
+
+ Clients[targetUser.ConnectedClients.First().Id].logOut(rooms);
+ }
}
}
View
@@ -790,6 +790,9 @@
<Content Include="Scripts\bootstrap.js" />
<Content Include="Scripts\bootstrap.min.js" />
<Content Include="robots.txt" />
+ <EmbeddedResource Include="Migrations\201208211555032_BanUser.resx">
+ <DependentUpon>201208211555032_BanUser.cs</DependentUpon>
+ </EmbeddedResource>
<None Include="Scripts\jquery-1.8.0.intellisense.js">
<DependentUpon>jquery-1.8.0.js</DependentUpon>
</None>
@@ -847,6 +850,7 @@
</Content>
</ItemGroup>
<ItemGroup>
+ <Compile Include="Commands\BanCommand.cs" />
<Compile Include="Commands\CommandMetaData.cs" />
<Compile Include="Commands\WelcomeCommand.cs" />
<Compile Include="Commands\UpdateCommand.cs" />
@@ -855,6 +859,10 @@
<Compile Include="Migrations\201206201924146_RoomWelcome.Designer.cs">
<DependentUpon>201206201924146_RoomWelcome.cs</DependentUpon>
</Compile>
+ <Compile Include="Migrations\201208211555032_BanUser.cs" />
+ <Compile Include="Migrations\201208211555032_BanUser.Designer.cs">
+ <DependentUpon>201208211555032_BanUser.cs</DependentUpon>
+ </Compile>
<Compile Include="WebApi\Model\ErrorModel.cs" />
<Compile Include="Infrastructure\HttpRequestExtensions.cs" />
<Compile Include="WebApi\MessagesController.cs" />
Oops, something went wrong.
@@ -0,0 +1,18 @@
+namespace JabbR.Models.Migrations
+{
+ using System;
+ using System.Data.Entity.Migrations;
+
+ public partial class BanUser : DbMigration
+ {
+ public override void Up()
+ {
+ AddColumn("ChatUsers", "IsBanned", c => c.Boolean(nullable: false, defaultValue: false));
+ }
+
+ public override void Down()
+ {
+ DropColumn("ChatUsers", "IsBanned");
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit a2405d0

Please sign in to comment.