Added groups & permissions. Fixed 7tv reconnection. Added more subcommands for refresh.
This commit is contained in:
75
Chat/Groups/ChatterGroupManager.cs
Normal file
75
Chat/Groups/ChatterGroupManager.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using Serilog;
|
||||
|
||||
namespace TwitchChatTTS.Chat.Groups
|
||||
{
|
||||
public class ChatterGroupManager : IChatterGroupManager
|
||||
{
|
||||
private readonly IDictionary<string, Group> _groups;
|
||||
private readonly IDictionary<long, ICollection<string>> _chatters;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
|
||||
public ChatterGroupManager(ILogger logger) {
|
||||
_logger = logger;
|
||||
_groups = new ConcurrentDictionary<string, Group>();
|
||||
_chatters = new ConcurrentDictionary<long, ICollection<string>>();
|
||||
}
|
||||
|
||||
public void Add(Group group) {
|
||||
_groups.Add(group.Name, group);
|
||||
}
|
||||
|
||||
public void Add(long chatter, string groupName) {
|
||||
_chatters.Add(chatter, new List<string>() { groupName });
|
||||
}
|
||||
|
||||
public void Add(long chatter, ICollection<string> groupNames) {
|
||||
if (_chatters.TryGetValue(chatter, out var list)) {
|
||||
foreach (var group in groupNames)
|
||||
list.Add(group);
|
||||
} else
|
||||
_chatters.Add(chatter, groupNames);
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
_groups.Clear();
|
||||
_chatters.Clear();
|
||||
}
|
||||
|
||||
public Group? Get(string groupName) {
|
||||
if (_groups.TryGetValue(groupName, out var group))
|
||||
return group;
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetGroupNamesFor(long chatter) {
|
||||
if (_chatters.TryGetValue(chatter, out var groups))
|
||||
return groups.Select(g => _groups[g].Name);
|
||||
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
public int GetPriorityFor(long chatter) {
|
||||
if (!_chatters.TryGetValue(chatter, out var groups))
|
||||
return 0;
|
||||
|
||||
return GetPriorityFor(groups);
|
||||
}
|
||||
|
||||
public int GetPriorityFor(IEnumerable<string> groupNames) {
|
||||
return groupNames.Select(g => _groups.TryGetValue(g, out var group) ? group : null).Where(g => g != null).Max(g => g.Priority);
|
||||
}
|
||||
|
||||
public bool Remove(long chatterId, string groupId) {
|
||||
if (_chatters.TryGetValue(chatterId, out var groups)) {
|
||||
groups.Remove(groupId);
|
||||
_logger.Debug($"Removed chatter from group [chatter id: {chatterId}][group name: {_groups[groupId]}][group id: {groupId}]");
|
||||
return true;
|
||||
}
|
||||
_logger.Debug($"Failed to remove chatter from group [chatter id: {chatterId}][group name: {_groups[groupId]}][group id: {groupId}]");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
9
Chat/Groups/Group.cs
Normal file
9
Chat/Groups/Group.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace TwitchChatTTS.Chat.Groups
|
||||
{
|
||||
public class Group
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int Priority { get; set; }
|
||||
}
|
||||
}
|
||||
8
Chat/Groups/GroupChatter.cs
Normal file
8
Chat/Groups/GroupChatter.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace TwitchChatTTS.Chat.Groups
|
||||
{
|
||||
public class GroupChatter
|
||||
{
|
||||
public string GroupId { get; set; }
|
||||
public long ChatterId { get; set;}
|
||||
}
|
||||
}
|
||||
15
Chat/Groups/IChatterGroupManager.cs
Normal file
15
Chat/Groups/IChatterGroupManager.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace TwitchChatTTS.Chat.Groups
|
||||
{
|
||||
public interface IChatterGroupManager
|
||||
{
|
||||
void Add(Group group);
|
||||
void Add(long chatter, string group);
|
||||
void Add(long chatter, ICollection<string> groupIds);
|
||||
void Clear();
|
||||
Group? Get(string groupId);
|
||||
IEnumerable<string> GetGroupNamesFor(long chatter);
|
||||
int GetPriorityFor(long chatter);
|
||||
int GetPriorityFor(IEnumerable<string> groupIds);
|
||||
bool Remove(long chatter, string groupId);
|
||||
}
|
||||
}
|
||||
10
Chat/Groups/Permissions/GroupPermission.cs
Normal file
10
Chat/Groups/Permissions/GroupPermission.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace TwitchChatTTS.Chat.Groups.Permissions
|
||||
{
|
||||
public class GroupPermission
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string GroupId { get; set; }
|
||||
public string Path { get; set; }
|
||||
public bool? Allow { get; set; }
|
||||
}
|
||||
}
|
||||
145
Chat/Groups/Permissions/GroupPermissionManager.cs
Normal file
145
Chat/Groups/Permissions/GroupPermissionManager.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using Serilog;
|
||||
|
||||
namespace TwitchChatTTS.Chat.Groups.Permissions
|
||||
{
|
||||
public class GroupPermissionManager : IGroupPermissionManager
|
||||
{
|
||||
private PermissionNode _root;
|
||||
private ILogger _logger;
|
||||
|
||||
|
||||
public GroupPermissionManager(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_root = new PermissionNode(string.Empty, null, null);
|
||||
}
|
||||
|
||||
|
||||
public bool? CheckIfAllowed(string path)
|
||||
{
|
||||
var res = Get(path)?.Allow;
|
||||
_logger.Debug($"Permission Node GET {path} = {res?.ToString() ?? "null"}");
|
||||
return res;
|
||||
}
|
||||
|
||||
public bool? CheckIfAllowed(IEnumerable<string> groups, string path) {
|
||||
bool overall = false;
|
||||
foreach (var group in groups) {
|
||||
var result = CheckIfAllowed($"{group}.{path}");
|
||||
if (result == false)
|
||||
return false;
|
||||
if (result == true)
|
||||
overall = true;
|
||||
}
|
||||
return overall ? true : null;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (_root.Children != null)
|
||||
_root.Children.Clear();
|
||||
}
|
||||
|
||||
public bool Remove(string path)
|
||||
{
|
||||
var node = Get(path);
|
||||
if (node == null || node.Parent == null)
|
||||
return false;
|
||||
|
||||
var parts = path.Split('.');
|
||||
var last = parts.Last();
|
||||
if (parts.Length > 1 && parts[parts.Length - 1] == node.Parent.Name || parts.Length == 1 && node.Parent.Name == null)
|
||||
{
|
||||
node.Parent.Remove(last);
|
||||
_logger.Debug($"Permission Node REMOVE priv {path}");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Set(string path, bool? allow)
|
||||
{
|
||||
var node = Get(path, true);
|
||||
node.Allow = allow;
|
||||
_logger.Debug($"Permission Node ADD {path} = {allow?.ToString() ?? "null"}");
|
||||
}
|
||||
|
||||
private PermissionNode Get(string path, bool edit = false)
|
||||
{
|
||||
return Get(_root, path.ToLower(), edit);
|
||||
}
|
||||
|
||||
private PermissionNode Get(PermissionNode node, string path, bool edit)
|
||||
{
|
||||
if (path.Length == 0)
|
||||
return node;
|
||||
|
||||
var parts = path.Split('.');
|
||||
var name = parts.First();
|
||||
var next = node.Children?.FirstOrDefault(n => n.Name == name);
|
||||
if (next == null)
|
||||
{
|
||||
if (!edit)
|
||||
return node;
|
||||
|
||||
next = new PermissionNode(name, node, null);
|
||||
node.Add(next);
|
||||
}
|
||||
return Get(next, string.Join('.', parts.Skip(1)), edit);
|
||||
}
|
||||
}
|
||||
|
||||
internal class PermissionNode
|
||||
{
|
||||
public string Name { get; }
|
||||
public bool? Allow
|
||||
{
|
||||
get
|
||||
{
|
||||
var current = this;
|
||||
while (current._allow == null && current._parent != null)
|
||||
current = current._parent;
|
||||
return current._allow;
|
||||
}
|
||||
set => _allow = value;
|
||||
}
|
||||
public int Priority;
|
||||
internal PermissionNode? Parent { get => _parent; }
|
||||
public IList<PermissionNode>? Children { get => _children == null ? null : new ReadOnlyCollection<PermissionNode>(_children); }
|
||||
|
||||
private bool? _allow;
|
||||
private PermissionNode? _parent;
|
||||
private IList<PermissionNode>? _children;
|
||||
|
||||
|
||||
public PermissionNode(string name, PermissionNode? parent, bool? allow)
|
||||
{
|
||||
Name = name;
|
||||
_parent = parent;
|
||||
_allow = allow;
|
||||
}
|
||||
|
||||
internal void Add(PermissionNode child)
|
||||
{
|
||||
if (_children == null)
|
||||
_children = new List<PermissionNode>();
|
||||
_children.Add(child);
|
||||
}
|
||||
|
||||
public void Remove(string name)
|
||||
{
|
||||
if (_children == null || !_children.Any())
|
||||
return;
|
||||
|
||||
for (var i = 0; i < _children.Count; i++)
|
||||
{
|
||||
if (_children[i].Name == name)
|
||||
{
|
||||
_children.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Chat/Groups/Permissions/IGroupPermissionManager.cs
Normal file
11
Chat/Groups/Permissions/IGroupPermissionManager.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace TwitchChatTTS.Chat.Groups.Permissions
|
||||
{
|
||||
public interface IGroupPermissionManager
|
||||
{
|
||||
void Set(string path, bool? allow);
|
||||
bool? CheckIfAllowed(string path);
|
||||
bool? CheckIfAllowed(IEnumerable<string> groups, string path);
|
||||
void Clear();
|
||||
bool Remove(string path);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user