Compare commits

..

2 Commits

Author SHA1 Message Date
e7b70468ae clearer definition of the concept of permission 2023-11-30 12:50:51 -05:00
47f382df19 more permission definition 2023-11-30 12:49:40 -05:00
16 changed files with 186 additions and 26 deletions

View File

@ -22,7 +22,7 @@ public class GeneralSnarkCloudNative : Behavior
if(Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id))
return false;
if(message.Channel.EffectivePermissions.ReactionsPossible == true)
if(message.Channel.EffectivePermissions.ReactionsPossible)
return false;
if((MeannessFilterLevel)message.Channel.EffectivePermissions.MeannessFilterLevel < MeannessFilterLevel.Medium)

28
Behavior/RoomRead.cs Normal file
View File

@ -0,0 +1,28 @@
namespace vassago.Behavior;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using vassago.Models;
[StaticPlz]
public class RoomRead : Behavior
{
public override string Name => "Room Read";
public override string Trigger => "roomread";
public override async Task<bool> ActOn(Message message)
{
var sb = new StringBuilder();
sb.Append("Channel owned by: ");
sb.Append("🤷");
sb.Append(". Meanness level: ");
sb.Append(message.Channel.EffectivePermissions.MeannessFilterLevel.GetDescription());
sb.Append(". Lewdness level: ");
sb.Append(message.Channel.EffectivePermissions.LewdnessFilterLevel.GetDescription());
sb.Append(".");
await message.Channel.SendMessage(sb.ToString());
return true;
}
}

View File

@ -11,7 +11,14 @@ public class TwitchSummon : Behavior
public override string Trigger => "!twitchsummon";
//TODO: Permission!
//TODO: Permission! anyone can summon from anywhere... anyone can summon to themselves.
//I think given the bot's (hopeful) ability to play nice with others - anyone can summon it anywhere
//HOWEVER, if not-the-broadcaster summons it, 1) all channel permissions to strict and 2) auto-disconnect on stream end
//i don't know if the twitch *chat* interface has knowledge of if the stream ends. maybe auto-disconnect after like 2 hours?
public override bool ShouldAct(Message message)
{
return true;
}
public override async Task<bool> ActOn(Message message)
{

View File

@ -16,7 +16,10 @@ public class TwitchDismiss : Behavior
if(message.MentionsMe &&
(Regex.IsMatch(message.Content.ToLower(), "\\bbegone\\b") || Regex.IsMatch(message.Content.ToLower(), "\\bfuck off\\b")))
{
//TODO: PERMISSION!
//TODO: PERMISSION! who can dismiss me? pretty simple list:
//1) anyone in the channel with authority*
//2) whoever summoned me
//* i don't know if the twitch *chat* interface will tell me if someone's a mod.
return true;
}
return false;

View File

@ -26,8 +26,6 @@ public class Account
}
public bool IsBot { get; set; } //webhook counts
public Channel SeenInChannel { get; set; }
//permissions are per account-in-channel or per-user, and always propagate down. and since protocol will be a channel, I'll set the "is adam" permission on myself 1x/protocol.
public List<Enumerations.WellknownPermissions> PermissionTags{get;set;}
public string Protocol { get; set; }
public User IsUser {get; set;}
}

View File

@ -14,7 +14,7 @@ public class Channel
public string ExternalId { get; set; }
public string DisplayName { get; set; }
public bool IsDM { get; set; }
public PermissionSettings Permissions { get; set; }
public ChannelPermissions Permissions { get; set; }
public List<Channel> SubChannels { get; set; }
public Channel ParentChannel { get; set; }
public string Protocol { get; set; }
@ -33,11 +33,11 @@ public class Channel
{
get
{
PermissionSettings toReturn = Permissions ?? new PermissionSettings();
ChannelPermissions toReturn = Permissions ?? new ChannelPermissions();
return GetEffectivePermissions(ref toReturn).Definite();
}
}
private PermissionSettings GetEffectivePermissions(ref PermissionSettings settings)
private ChannelPermissions GetEffectivePermissions(ref ChannelPermissions settings)
{
if(settings == null) throw new ArgumentNullException();
settings.LewdnessFilterLevel = settings.LewdnessFilterLevel ?? Permissions?.LewdnessFilterLevel;

View File

@ -3,7 +3,7 @@ namespace vassago.Models;
using System;
using System.ComponentModel.DataAnnotations.Schema;
public class PermissionSettings
public class ChannelPermissions
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
@ -13,6 +13,7 @@ public class PermissionSettings
public bool? ReactionsPossible { get; set; }
public Enumerations.LewdnessFilterLevel? LewdnessFilterLevel { get; set; }
public Enumerations.MeannessFilterLevel? MeannessFilterLevel { get; set; }
public Enumerations.VerbosityFilterLevel? VerbosityFilterLevel { get; set; }
internal DefinitePermissionSettings Definite()
{
@ -23,6 +24,7 @@ public class PermissionSettings
LinksAllowed = this.LinksAllowed ?? false,
LewdnessFilterLevel = this.LewdnessFilterLevel ?? Enumerations.LewdnessFilterLevel.G,
MeannessFilterLevel = this.MeannessFilterLevel ?? Enumerations.MeannessFilterLevel.Strict,
VerbosityFilterLevel = this.VerbosityFilterLevel ?? Enumerations.VerbosityFilterLevel.Pithy,
ReactionsPossible = this.ReactionsPossible ?? false
};
}

View File

@ -9,7 +9,7 @@ public class ChattingContext : DbContext
public DbSet<Channel> Channels { get; set; }
//public DbSet<Emoji> Emoji {get;set;}
public DbSet<Message> Messages { get; set; }
public DbSet<PermissionSettings> PermissionSettings{get;set;}
public DbSet<ChannelPermissions> PermissionSettings{get;set;}
public DbSet<Account> Accounts { get; set; }
public DbSet<User> Users { get; set; }

View File

@ -15,7 +15,7 @@ public static class Enumerations
[Description("polite company")]
Moderate,
[Description(";) ;) ;)")]
unrestricted
Unrestricted
}
public enum MeannessFilterLevel
{
@ -23,13 +23,17 @@ public static class Enumerations
Strict,
[Description("a bit cheeky")]
Medium,
[Description("387.44 million miles of printed circuits, etc")]
[Description("387.44m mi of printed circuits")]
Unrestricted
}
public enum WellknownPermissions
public enum VerbosityFilterLevel
{
Master, //e.g., me. not that I think this would ever be released?
TwitchSummon,
[Description("stfu")]
Quiet,
[Description("pithy")]
Pithy,
[Description("you want text i'll GIVE you text")]
Unrestricted
}
public static string GetDescription<T>(this T enumerationValue)

109
Models/FeaturePermission.cs Normal file
View File

@ -0,0 +1,109 @@
namespace vassago.Models;
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;
using System.Threading.Tasks;
using Discord.WebSocket;
using static vassago.Models.Enumerations;
public enum WellknownPermissions
{
Administrator,
TwitchSummon,
}
public class FeaturePermission
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public string InternalName { get; set; }
public WellknownPermissions? InternalTag { get; set; }
//a permissions-needing-feature can determine how to use these, but a default "matches" is provided
//for a message to "match", it must match in every category for which there are candidates.
//e.g., Administrator is going to be restricted to Users only, and that'll be me
//e.g., my future Torrent feature would be restricted to accounts and channels.
//hmmm, what would be inheritable and what wouldn't?
public IEnumerable<User> RestrictedToUsers { get; set; }
public IEnumerable<Account> RestrictedToAccounts { get; set; }
public IEnumerable<Channel> RestrictedToChannels { get; set; }
public bool Inheritable { get; set; } = true;
public bool Matches(Message message)
{
if(RestrictedToUsers?.Count() > 0)
{
if(RestrictedToUsers.FirstOrDefault(u => u.Id == message.Author.IsUser.Id) == null)
{
return false;
}
}
if(RestrictedToChannels?.Count() > 0)
{
if(Inheritable)
{
var found = false;
var walker = message.Channel;
if (RestrictedToChannels.FirstOrDefault(c => c.Id == walker.Id) != null)
{
found = true;
}
else
{
while (walker.ParentChannel != null)
{
walker = walker.ParentChannel;
if(walker.Users.FirstOrDefault(a => a.ExternalId == message.Author.ExternalId) == null)
{
//the chain is broken; I don't exist in this channel
break;
}
if (RestrictedToChannels.FirstOrDefault(c => c.Id == walker.Id) != null)
{
found = true;
break;
}
}
}
if (found)
{
if(RestrictedToAccounts?.Count() > 0)
{
//walker is the "actual" restricted-to channel, but we're inheriting
if(walker.Users.FirstOrDefault(a => a.Id == message.Author.Id) == null)
{
return false;
}
}
}
else
{
return false;
}
}
else
{
if(RestrictedToChannels.FirstOrDefault(c => c.Id == message.Channel.Id) == null)
{
return false;
}
}
}
if(RestrictedToAccounts?.Count() > 0)
{
if(RestrictedToAccounts.FirstOrDefault(a => a.Id == message.Author.Id) == null)
{
return false;
}
}
//if I got all the way down here, I must be good
return true;
}
}

View File

@ -10,6 +10,16 @@ public class User
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public List<Account> Accounts { get; set; }
//permissions are per account-in-channel or per-user, and always propagate down. and since protocol will be a channel, I'll set the "is adam" permission on myself 1x/protocol.
public List<Enumerations.WellknownPermissions> PermissionTags{get;set;}
public string DisplayName
{
get
{
return Accounts.Select(a => a.DisplayName).Distinct()
.MaxBy(distinctName =>
Accounts.Select(a => a.DisplayName)
.Where(selectedName => selectedName == distinctName).Count()
);
}
}
}

View File

@ -58,7 +58,7 @@ public class DiscordInterface
protocolAsChannel = new Channel()
{
DisplayName = "discord (itself)",
Permissions = new PermissionSettings()
Permissions = new Models.ChannelPermissions()
{
MeannessFilterLevel = Enumerations.MeannessFilterLevel.Strict,
LewdnessFilterLevel = Enumerations.LewdnessFilterLevel.Moderate,
@ -291,7 +291,7 @@ public class DiscordInterface
c.Protocol = protocolAsChannel.Protocol;
c.ParentChannel = protocolAsChannel;
c.SubChannels = c.SubChannels ?? new List<Channel>();
c.Permissions = c.Permissions ?? new PermissionSettings();
c.Permissions = c.Permissions ?? new Models.ChannelPermissions();
c.Permissions.MaxAttachmentBytes = channel.MaxUploadLimit;
c.SendMessage = (t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; cannot accept text"); };

View File

@ -38,7 +38,7 @@ public class TwitchInterface
protocolAsChannel = new Channel()
{
DisplayName = "twitch (itself)",
Permissions = new PermissionSettings()
Permissions = new ChannelPermissions()
{
MeannessFilterLevel = Enumerations.MeannessFilterLevel.Medium,
LewdnessFilterLevel = Enumerations.LewdnessFilterLevel.G,

View File

@ -10,7 +10,7 @@
@Html.DisplayNameFor(model => model.Id)
</th>
<th>
@Html.DisplayNameFor(model => model.PermissionTags)
name*
</th>
<th>
number of associated accounts
@ -24,7 +24,7 @@
@Html.DisplayFor(modelItem => item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.PermissionTags)
@Html.DisplayFor(modelItem => item.DisplayName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Accounts.Count)x

View File

@ -40,7 +40,6 @@ A ghost walked into a bar and ordered a shot of vodka. The bartender said, So
A blind man walked into a bar. and a table. and a chair.
How do you make holy water? You boil the hell out of it.
My teachers told me Id never amount to much because I procrastinate so much. I told them, “Just you wait!”
ברכב שנוסע על 4 גלגלים, איזה גלגל לא זז? גלגל רזרבי
what's the best part about living in switzerland? well the flag is a big plus.
I asked my date to meet me at the gym today. She didn't show up. That's when I knew we weren't gonna work out.
The CEO of IKEA was elected Prime Minister in Sweden. He should have his cabinet together by the end of the weekend.