Skip to content

Instantly share code, notes, and snippets.

@ToJans
Created December 20, 2011 12:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ToJans/1501392 to your computer and use it in GitHub Desktop.
Save ToJans/1501392 to your computer and use it in GitHub Desktop.
Scritchy now supports validation, convention = "Can"+commandname, this works both in the AR and in stateless handlers !
using Scritchy.Domain;
namespace AnotherChat.Domain
{
public class Room : AR
{
int UserCount = 0;
public void JoinRoom(string UserId)
{
if (UserCount == 0)
Changes += new Events.UserCreatedRoom
{
UserId = UserId,
RoomId = Id
};
Changes += new Events.UserJoinedRoom
{
UserId = UserId,
RoomId = Id,
};
}
// validator in the AR for demo purpose; the last user can not leave the room
public void CanLeaveRoom()
{
Guard.Against(UserCount == 1, "You can not leave the room as you are the last user here");
}
public void LeaveRoom(string UserId)
{
Changes += new Events.UserLeftRoom
{
UserId = UserId,
RoomId = Id
};
}
public void PostMessage(string UserId, string Message)
{
Changes += new Events.MessagePosted
{
UserId = UserId,
RoomId = Id,
Message = Message
};
}
public void BanUser(string BannedByUserId, string BannedUserId, string Reason)
{
Changes += new Events.UserBanned
{
BannedByUserId = BannedByUserId,
BannedUserId = BannedUserId,
RoomId = Id,
Reason = Reason
};
}
public void UnbanUser(string UnbannedByUserId, string UnbannedUserId)
{
Changes += new Events.UserUnbanned
{
UnbannedByUserId = UnbannedByUserId,
UnbannedUserId = UnbannedUserId,
RoomId = Id
};
}
public void MuteUser(string MutedByUserId, string MutedUserId, string Reason)
{
Changes += new Events.UserMuted
{
MutedByUserId = MutedByUserId,
MutedUserId = MutedUserId,
RoomId = Id,
Reason = Reason
};
}
public void UnmuteUser(string UnmutedByUserId, string UnmutedUserId)
{
Changes += new Events.UserUnmuted
{
UnbannedByUserId = UnmutedByUserId,
UnbannedUserId = UnmutedUserId,
RoomId = Id
};
}
public void OnUserJoinedRoom()
{
UserCount++;
}
public void UserLeftRoom()
{
UserCount--;
}
}
}
using Scritchy.Domain;
namespace AnotherChat.Domain.Security
{
public class RoomSecurityHandler:SecurityHandler
{
public void CanJoinRoom(string RoomId, string UserId)
{
Guard.Against(GetClaimSet(RoomId)[UserId] == UserRole.NothingAllowed, "You do not have access to this room");
}
public void CanPostMessage(string RoomId, string UserId)
{
Guard.Against(GetClaimSet(RoomId)[UserId] < UserRole.Participant, "You are not allowed to post messages in this room");
}
public void CanBanUser(string RoomId, string BannedByUserId, string BannedUserId)
{
Guard.Against(GetClaimSet(RoomId)[BannedByUserId] < UserRole.Moderator, "You do not have sufficient permissions to perform this action");
Guard.Against(GetClaimSet(RoomId)[BannedUserId] == UserRole.NothingAllowed, "This user is already banned");
}
public void CanUnbanUser(string RoomId, string UnbannedByUserId, string UnbannedUserId)
{
Guard.Against(GetClaimSet(RoomId)[UnbannedByUserId] < UserRole.Moderator, "You do not have sufficient permissions to perform this action");
Guard.Against(GetClaimSet(RoomId)[UnbannedUserId] != UserRole.NothingAllowed, "This user is not banned");
}
public void CanMuteUser(string RoomId, string MutedByUserId, string MutedUserId)
{
Guard.Against(GetClaimSet(RoomId)[MutedByUserId] < UserRole.Moderator, "You do not have sufficient permissions to perform this action");
Guard.Against(GetClaimSet(RoomId)[MutedUserId] <= UserRole.Spectator, "This user is already a spectator");
}
public void CanUnmuteUser(string RoomId, string UnmutedByUserId, string UnmutedUserId)
{
Guard.Against(GetClaimSet(RoomId)[UnmutedByUserId] < UserRole.Moderator, "You do not have sufficient permissions to perform this action");
Guard.Against(GetClaimSet(RoomId)[UnmutedUserId] > UserRole.Spectator, "This user is not muted");
}
public void OnRoomCreated(string RoomId, string UserId)
{
GetClaimSet(RoomId)[UserId] |= UserRole.Administrator;
}
public void OnRoomJoined(string RoomId, string UserId)
{
GetClaimSet(RoomId)[UserId] |= GetClaimSet(RoomId).DefaultRole;
}
public void OnUserBanned(string RoomId, string BannedUserId)
{
GetClaimSet(RoomId)[BannedUserId] &= UserRole.NothingAllowed;
}
public void OnUserMuted(string RoomId, string MutedUserId)
{
GetClaimSet(RoomId)[MutedUserId] &= UserRole.Spectator;
}
public void OnUserUnbanned(string RoomId, string UnbannedUserId)
{
GetClaimSet(RoomId)[UnbannedUserId] |= GetClaimSet(RoomId).DefaultRole;
}
public void OnUserUnmuted(string RoomId, string UnmutedUserId)
{
GetClaimSet(RoomId)[UnmutedUserId] |= UserRole.Participant;
}
}
}
using System.Collections.Generic;
namespace AnotherChat.Domain.Security
{
public abstract class SecurityHandler
{
protected enum UserRole
{
NothingAllowed = 0,
ReadingAllowed = 1,
WritingAllowed = 2,
AdministrationAllowed = 4,
HasOwnership = 8,
Spectator = ReadingAllowed,
Participant = ReadingAllowed + WritingAllowed,
Moderator = Participant + AdministrationAllowed,
Administrator = Moderator + HasOwnership
}
protected class ClaimSet
{
Dictionary<string, UserRole> UserRoles = new Dictionary<string, UserRole>();
public UserRole DefaultRole = UserRole.Participant;
public UserRole this[string userId]
{
get {
return UserRoles.ContainsKey(userId) ? UserRoles[userId] : DefaultRole;
}
set {
UserRoles[userId] = DefaultRole;
}
}
}
Dictionary<string, ClaimSet> Claims = new Dictionary<string, ClaimSet>();
protected ClaimSet GetClaimSet(string RoomId)
{
Claims[RoomId] = Claims[RoomId] ?? new ClaimSet();
return Claims[RoomId];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment