More work on permission system, fixes

This commit is contained in:
Kwoth 2016-09-22 20:53:49 +02:00
parent 2f859ad32d
commit 1a2d1398a7
15 changed files with 326 additions and 640 deletions

View File

@ -1,556 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using NadekoBot.Services.Database.Impl;
namespace NadekoBot.Migrations
{
[DbContext(typeof(NadekoSqliteContext))]
[Migration("20160910180231_first")]
partial class first
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
modelBuilder
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431");
modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<ulong>("ItemId");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("BlacklistItem");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("BufferSize");
b.Property<float>("CurrencyGenerationChance");
b.Property<int>("CurrencyGenerationCooldown");
b.Property<string>("CurrencyName");
b.Property<string>("CurrencyPluralName");
b.Property<string>("CurrencySign");
b.Property<bool>("DontJoinServers");
b.Property<bool>("ForwardMessages");
b.Property<bool>("ForwardToAllOwners");
b.Property<string>("RemindMessageFormat");
b.Property<bool>("RotatingStatuses");
b.HasKey("Id");
b.ToTable("BotConfig");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("BaseDestroyed");
b.Property<string>("CallUser");
b.Property<int>("ClashWarId");
b.Property<int>("Stars");
b.Property<DateTime>("TimeAdded");
b.HasKey("Id");
b.HasIndex("ClashWarId");
b.ToTable("ClashCallers");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashWar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<string>("EnemyClan");
b.Property<ulong>("GuildId");
b.Property<int>("Size");
b.Property<DateTime>("StartedAt");
b.Property<int>("WarState");
b.HasKey("Id");
b.ToTable("ClashOfClans");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ConvertUnit", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("InternalTrigger");
b.Property<decimal>("Modifier");
b.Property<string>("UnitType");
b.HasKey("Id");
b.ToTable("ConversionUnits");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Currency", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<long>("Amount");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.HasIndex("UserId")
.IsUnique();
b.ToTable("Currency");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Amount");
b.Property<string>("Name");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.HasIndex("UserId")
.IsUnique();
b.ToTable("Donators");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Text");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("EightBallResponses");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("GuildConfigId");
b.Property<ulong>("GuildId");
b.Property<bool>("LastStatus");
b.Property<int>("Type");
b.Property<string>("Username");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("FollowedStream");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("AutoAssignRoleId");
b.Property<bool>("AutoDeleteByeMessages");
b.Property<bool>("AutoDeleteGreetMessages");
b.Property<int>("AutoDeleteGreetMessagesTimer");
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
b.Property<ulong>("ByeMessageChannelId");
b.Property<string>("ChannelByeMessageText");
b.Property<string>("ChannelGreetMessageText");
b.Property<float>("DefaultMusicVolume");
b.Property<bool>("DeleteMessageOnCommand");
b.Property<string>("DmGreetMessageText");
b.Property<bool>("ExclusiveSelfAssignedRoles");
b.Property<ulong?>("GenerateCurrencyChannelId");
b.Property<ulong>("GreetMessageChannelId");
b.Property<ulong>("GuildId");
b.Property<int?>("LogSettingId");
b.Property<bool>("SendChannelByeMessage");
b.Property<bool>("SendChannelGreetMessage");
b.Property<bool>("SendDmGreetMessage");
b.Property<bool>("VoicePlusTextEnabled");
b.HasKey("Id");
b.HasIndex("GuildId")
.IsUnique();
b.HasIndex("LogSettingId");
b.ToTable("GuildConfigs");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("LogSettingId");
b.HasKey("Id");
b.HasIndex("LogSettingId");
b.ToTable("IgnoredLogChannels");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("LogSettingId");
b.HasKey("Id");
b.HasIndex("LogSettingId");
b.ToTable("IgnoredVoicePresenceCHannels");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("ChannelCreated");
b.Property<bool>("ChannelDestroyed");
b.Property<ulong>("ChannelId");
b.Property<bool>("ChannelUpdated");
b.Property<bool>("IsLogging");
b.Property<bool>("LogUserPresence");
b.Property<bool>("LogVoicePresence");
b.Property<bool>("MessageDeleted");
b.Property<bool>("MessageReceived");
b.Property<bool>("MessageUpdated");
b.Property<bool>("UserBanned");
b.Property<bool>("UserJoined");
b.Property<bool>("UserLeft");
b.Property<ulong>("UserPresenceChannelId");
b.Property<bool>("UserUnbanned");
b.Property<bool>("UserUpdated");
b.Property<ulong>("VoicePresenceChannelId");
b.HasKey("Id");
b.ToTable("LogSettings");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("BotConfigId");
b.Property<string>("ModuleName");
b.Property<string>("Prefix");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("ModulePrefixes");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Status");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("PlayingStatus");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("AuthorId");
b.Property<string>("AuthorName")
.IsRequired();
b.Property<ulong>("GuildId");
b.Property<string>("Keyword")
.IsRequired();
b.Property<string>("Text")
.IsRequired();
b.HasKey("Id");
b.ToTable("Quotes");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Icon");
b.Property<string>("Name");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("RaceAnimals");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<bool>("IsPrivate");
b.Property<string>("Message");
b.Property<ulong>("ServerId");
b.Property<ulong>("UserId");
b.Property<DateTime>("When");
b.HasKey("Id");
b.ToTable("Reminders");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<ulong>("GuildId");
b.Property<TimeSpan>("Interval");
b.Property<string>("Message");
b.HasKey("Id");
b.HasIndex("ChannelId")
.IsUnique();
b.ToTable("Repeaters");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("GuildId");
b.Property<ulong>("RoleId");
b.HasKey("Id");
b.HasIndex("GuildId", "RoleId")
.IsUnique();
b.ToTable("SelfAssignableRoles");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.TypingArticle", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Author");
b.Property<string>("Text");
b.HasKey("Id");
b.ToTable("TypingArticles");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
.WithMany("Blacklist")
.HasForeignKey("BotConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar")
.WithMany("Bases")
.HasForeignKey("ClashWarId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
.WithMany("EightBallResponses")
.HasForeignKey("BotConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
.WithMany("FollowedStreams")
.HasForeignKey("GuildConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
.WithMany()
.HasForeignKey("LogSettingId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
.WithMany("IgnoredChannels")
.HasForeignKey("LogSettingId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
.WithMany("IgnoredVoicePresenceChannelIds")
.HasForeignKey("LogSettingId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.BotConfig", "BotConfig")
.WithMany("ModulePrefixes")
.HasForeignKey("BotConfigId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
.WithMany("RotatingStatusMessages")
.HasForeignKey("BotConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
.WithMany("RaceAnimals")
.HasForeignKey("BotConfigId");
});
}
}
}

View File

@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace NadekoBot.Migrations
{
public partial class second : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Permission",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Autoincrement", true),
Command = table.Column<string>(nullable: true),
GuildConfigId = table.Column<int>(nullable: true),
Module = table.Column<string>(nullable: true),
State = table.Column<bool>(nullable: false),
Target = table.Column<string>(nullable: true),
TargetType = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Permission", x => x.Id);
table.ForeignKey(
name: "FK_Permission_GuildConfigs_GuildConfigId",
column: x => x.GuildConfigId,
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_Permission_GuildConfigId",
table: "Permission",
column: "GuildConfigId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Permission");
}
}
}

View File

@ -8,8 +8,8 @@ using NadekoBot.Services.Database.Impl;
namespace NadekoBot.Migrations namespace NadekoBot.Migrations
{ {
[DbContext(typeof(NadekoSqliteContext))] [DbContext(typeof(NadekoSqliteContext))]
[Migration("20160920004320_second")] [Migration("20160922170157_perms")]
partial class second partial class perms
{ {
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
{ {
@ -354,18 +354,18 @@ namespace NadekoBot.Migrations
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd(); .ValueGeneratedOnAdd();
b.Property<string>("Command");
b.Property<int?>("GuildConfigId"); b.Property<int?>("GuildConfigId");
b.Property<string>("Module"); b.Property<int>("PrimaryTarget");
b.Property<ulong>("PrimaryTargetId");
b.Property<int>("SecondaryTarget");
b.Property<string>("SecondaryTargetName");
b.Property<bool>("State"); b.Property<bool>("State");
b.Property<string>("Target");
b.Property<int>("TargetType");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");

View File

@ -4,7 +4,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
namespace NadekoBot.Migrations namespace NadekoBot.Migrations
{ {
public partial class first : Migration public partial class perms : Migration
{ {
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
@ -428,6 +428,30 @@ namespace NadekoBot.Migrations
onDelete: ReferentialAction.Restrict); onDelete: ReferentialAction.Restrict);
}); });
migrationBuilder.CreateTable(
name: "Permission",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Autoincrement", true),
GuildConfigId = table.Column<int>(nullable: true),
PrimaryTarget = table.Column<int>(nullable: false),
PrimaryTargetId = table.Column<ulong>(nullable: false),
SecondaryTarget = table.Column<int>(nullable: false),
SecondaryTargetName = table.Column<string>(nullable: true),
State = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Permission", x => x.Id);
table.ForeignKey(
name: "FK_Permission_GuildConfigs_GuildConfigId",
column: x => x.GuildConfigId,
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_BlacklistItem_BotConfigId", name: "IX_BlacklistItem_BotConfigId",
table: "BlacklistItem", table: "BlacklistItem",
@ -486,6 +510,11 @@ namespace NadekoBot.Migrations
table: "ModulePrefixes", table: "ModulePrefixes",
column: "BotConfigId"); column: "BotConfigId");
migrationBuilder.CreateIndex(
name: "IX_Permission_GuildConfigId",
table: "Permission",
column: "GuildConfigId");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_PlayingStatus_BotConfigId", name: "IX_PlayingStatus_BotConfigId",
table: "PlayingStatus", table: "PlayingStatus",
@ -541,6 +570,9 @@ namespace NadekoBot.Migrations
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "ModulePrefixes"); name: "ModulePrefixes");
migrationBuilder.DropTable(
name: "Permission");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "PlayingStatus"); name: "PlayingStatus");

View File

@ -353,18 +353,18 @@ namespace NadekoBot.Migrations
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd(); .ValueGeneratedOnAdd();
b.Property<string>("Command");
b.Property<int?>("GuildConfigId"); b.Property<int?>("GuildConfigId");
b.Property<string>("Module"); b.Property<int>("PrimaryTarget");
b.Property<ulong>("PrimaryTargetId");
b.Property<int>("SecondaryTarget");
b.Property<string>("SecondaryTargetName");
b.Property<bool>("State"); b.Property<bool>("State");
b.Property<string>("Target");
b.Property<int>("TargetType");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");

View File

@ -96,7 +96,7 @@ namespace NadekoBot.Modules.Gambling
{ {
try try
{ {
await raceChannel.SendMessageAsync($"🏁`Race is starting in 20 seconds or when the room is full. Type {NadekoBot.ModulePrefixes["Gambling"]}jr to join the race.`"); await raceChannel.SendMessageAsync($"🏁`Race is starting in 20 seconds or when the room is full. Type {NadekoBot.ModulePrefixes[typeof(Gambling).Name]}jr to join the race.`");
var t = await Task.WhenAny(Task.Delay(20000, token), fullgame); var t = await Task.WhenAny(Task.Delay(20000, token), fullgame);
Started = true; Started = true;
cancelSource.Cancel(); cancelSource.Cancel();

View File

@ -86,7 +86,7 @@ namespace NadekoBot.Modules.Games
{ {
var sent = await channel.SendFileAsync( var sent = await channel.SendFileAsync(
GetRandomCurrencyImagePath(), GetRandomCurrencyImagePath(),
$"❗ A random { Gambling.Gambling.CurrencyName } appeared! Pick it up by typing `{NadekoBot.ModulePrefixes["Gambling"]}pick`") $"❗ A random { Gambling.Gambling.CurrencyName } appeared! Pick it up by typing `{NadekoBot.ModulePrefixes[typeof(Games).Name]}pick`")
.ConfigureAwait(false); .ConfigureAwait(false);
plantedFlowers.AddOrUpdate(channel.Id, new List<IUserMessage>() { sent }, (id, old) => { old.Add(sent); return old; }); plantedFlowers.AddOrUpdate(channel.Id, new List<IUserMessage>() { sent }, (id, old) => { old.Add(sent); return old; });
} }
@ -148,7 +148,7 @@ namespace NadekoBot.Modules.Games
IUserMessage msg; IUserMessage msg;
var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(Gambling.Gambling.CurrencyName[0]); var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(Gambling.Gambling.CurrencyName[0]);
var msgToSend = $"Oh how Nice! **{imsg.Author.Username}** planted {(vowelFirst ? "an" : "a")} {Gambling.Gambling.CurrencyName}. Pick it using {NadekoBot.ModulePrefixes["Games"]}pick"; var msgToSend = $"Oh how Nice! **{imsg.Author.Username}** planted {(vowelFirst ? "an" : "a")} {Gambling.Gambling.CurrencyName}. Pick it using {NadekoBot.ModulePrefixes[typeof(Gambling.Gambling).Name]}pick";
if (file == null) if (file == null)
{ {
msg = await channel.SendMessageAsync(Gambling.Gambling.CurrencySign).ConfigureAwait(false); msg = await channel.SendMessageAsync(Gambling.Gambling.CurrencySign).ConfigureAwait(false);

View File

@ -17,7 +17,7 @@ using NadekoBot.Services.Database;
namespace NadekoBot.Modules.Music namespace NadekoBot.Modules.Music
{ {
[NadekoModule("ClashOfClans", "!!")] [NadekoModule("Music", "!!")]
public partial class Music : DiscordModule public partial class Music : DiscordModule
{ {
public static ConcurrentDictionary<ulong, MusicPlayer> MusicPlayers = new ConcurrentDictionary<ulong, MusicPlayer>(); public static ConcurrentDictionary<ulong, MusicPlayer> MusicPlayers = new ConcurrentDictionary<ulong, MusicPlayer>();

View File

@ -0,0 +1,121 @@
using Discord;
using Discord.Commands;
using NadekoBot.Services.Database.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Permissions
{
public static class PermissionExtensions
{
public static bool CheckPermissions(this IEnumerable<Permission> permsEnumerable, IUserMessage message, Command command)
{
var perms = permsEnumerable as List<Permission> ?? permsEnumerable.ToList();
int throwaway;
return perms.CheckPermissions(message, command, out throwaway);
}
public static bool CheckPermissions(this IEnumerable<Permission> permsEnumerable, IUserMessage message, Command command, out int permIndex)
{
var perms = permsEnumerable as List<Permission> ?? permsEnumerable.ToList();
for (int i = 0; i < perms.Count; i++)
{
var perm = perms[i];
var result = perm.CheckPermission(message, command);
if (result == null)
{
continue;
}
else
{
permIndex = i + 1;
return result.Value;
}
}
permIndex = -1; //defaut behaviour
return true;
}
//null = not applicable
//true = applicable, allowed
//false = applicable, not allowed
public static bool? CheckPermission(this Permission perm, IUserMessage message, Command command)
{
if (!((perm.SecondaryTarget == SecondaryPermissionType.Command &&
perm.SecondaryTargetName == command.Text.ToLowerInvariant()) ||
(perm.SecondaryTarget == SecondaryPermissionType.Module &&
perm.SecondaryTargetName == command.Module.Name.ToLowerInvariant())))
return null;
switch (perm.PrimaryTarget)
{
case PrimaryPermissionType.User:
if (perm.PrimaryTargetId == message.Author.Id)
return perm.State;
break;
case PrimaryPermissionType.Channel:
if (perm.PrimaryTargetId == message.Channel.Id)
return perm.State;
break;
case PrimaryPermissionType.Role:
var guildUser = message.Author as IGuildUser;
if (guildUser == null)
break;
if (guildUser.Roles.Any(r => r.Id == perm.PrimaryTargetId))
return perm.State;
break;
}
return null;
}
public static string GetCommand(this Permission perm)
{
var com = NadekoBot.ModulePrefixes[typeof(Permissions).Name];
switch (perm.PrimaryTarget)
{
case PrimaryPermissionType.User:
com += "u";
break;
case PrimaryPermissionType.Channel:
com += "c";
break;
case PrimaryPermissionType.Role:
com += "r";
break;
}
switch (perm.SecondaryTarget)
{
case SecondaryPermissionType.Module:
com += "m";
break;
case SecondaryPermissionType.Command:
com += "c";
break;
}
com += " " + perm.SecondaryTargetName + " " + (perm.State ? "enable" : "disable") + " ";
switch (perm.PrimaryTarget)
{
case PrimaryPermissionType.User:
com += $"<@{perm.PrimaryTargetId}>";
break;
case PrimaryPermissionType.Channel:
com += $"<#{perm.PrimaryTargetId}>";
break;
case PrimaryPermissionType.Role:
com += $"<@&{perm.PrimaryTargetId}>";
break;
}
return com;
}
}
}

View File

@ -20,6 +20,27 @@ namespace NadekoBot.Modules.Permissions
{ {
} }
[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias]
[RequireContext(ContextType.Guild)]
public async Task ListPerms(IUserMessage msg)
{
var channel = (ITextChannel)msg.Channel;
string toSend = "";
using (var uow = DbHandler.UnitOfWork())
{
var perms = uow.GuildConfigs.For(channel.Guild.Id).Permissions;
var i = 1;
toSend = String.Join("\n", perms.Select(p => $"`{(i++)}.` {p.GetCommand()}"));
}
if (string.IsNullOrWhiteSpace(toSend))
await channel.SendMessageAsync("`No permissions set.`").ConfigureAwait(false);
else
await channel.SendMessageAsync(toSend).ConfigureAwait(false);
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias] [LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task UsrCmd(IUserMessage imsg, Command command, PermissionAction action, IGuildUser user) public async Task UsrCmd(IUserMessage imsg, Command command, PermissionAction action, IGuildUser user)
@ -30,14 +51,15 @@ namespace NadekoBot.Modules.Permissions
{ {
uow.GuildConfigs.For(channel.Guild.Id).Permissions.Add(new Permission uow.GuildConfigs.For(channel.Guild.Id).Permissions.Add(new Permission
{ {
TargetType = PermissionType.User, PrimaryTarget = PrimaryPermissionType.User,
Target = user.Id.ToString(), PrimaryTargetId = user.Id,
Command = command.Text.ToLowerInvariant(), SecondaryTarget = SecondaryPermissionType.Command,
SecondaryTargetName = command.Text.ToLowerInvariant(),
State = action.Value, State = action.Value,
}); });
await uow.CompleteAsync(); await uow.CompleteAsync().ConfigureAwait(false);
} }
await channel.SendMessageAsync($"{(action.Value ? "Allowed" : "Denied")} usage of `{command.Text}` command for `{user}` user."); await channel.SendMessageAsync($"{(action.Value ? "Allowed" : "Denied")} usage of `{command.Text}` command for `{user}` user.").ConfigureAwait(false);
} }
[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias] [LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias]
@ -50,14 +72,15 @@ namespace NadekoBot.Modules.Permissions
{ {
uow.GuildConfigs.For(channel.Guild.Id).Permissions.Add(new Permission uow.GuildConfigs.For(channel.Guild.Id).Permissions.Add(new Permission
{ {
TargetType = PermissionType.User, PrimaryTarget = PrimaryPermissionType.User,
Target = user.Id.ToString(), PrimaryTargetId = user.Id,
Module = module.Name.ToLowerInvariant(), SecondaryTarget = SecondaryPermissionType.Module,
SecondaryTargetName = module.Name.ToLowerInvariant(),
State = action.Value, State = action.Value,
}); });
await uow.CompleteAsync(); await uow.CompleteAsync().ConfigureAwait(false);
} }
await channel.SendMessageAsync($"{(action.Value ? "Allowed" : "Denied")} usage of `{module.Name}` module for `{user}` user."); await channel.SendMessageAsync($"{(action.Value ? "Allowed" : "Denied")} usage of `{module.Name}` module for `{user}` user.").ConfigureAwait(false);
} }
} }
} }

View File

@ -3596,6 +3596,33 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Lists whole permission chain with their indexes..
/// </summary>
public static string listperms_desc {
get {
return ResourceManager.GetString("listperms_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `;lp`.
/// </summary>
public static string listperms_summary {
get {
return ResourceManager.GetString("listperms_summary", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to listperms lp.
/// </summary>
public static string listperms_text {
get {
return ResourceManager.GetString("listperms_text", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Lists all playing statuses with their corresponding number. **Bot Owner Only!**. /// Looks up a localized string similar to Lists all playing statuses with their corresponding number. **Bot Owner Only!**.
/// </summary> /// </summary>

View File

@ -2637,4 +2637,13 @@
<data name="cash_text" xml:space="preserve"> <data name="cash_text" xml:space="preserve">
<value>cash $$</value> <value>cash $$</value>
</data> </data>
<data name="listperms_desc" xml:space="preserve">
<value>Lists whole permission chain with their indexes.</value>
</data>
<data name="listperms_summary" xml:space="preserve">
<value>`;lp`</value>
</data>
<data name="listperms_text" xml:space="preserve">
<value>listperms lp</value>
</data>
</root> </root>

View File

@ -8,6 +8,9 @@ using Discord;
using NLog; using NLog;
using System.Diagnostics; using System.Diagnostics;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Services.Database;
using NadekoBot.Services.Database.Models;
using NadekoBot.Modules.Permissions;
namespace NadekoBot.Services namespace NadekoBot.Services
{ {
@ -33,11 +36,15 @@ namespace NadekoBot.Services
var usrMsg = msg as IUserMessage; var usrMsg = msg as IUserMessage;
if (usrMsg == null) if (usrMsg == null)
return Task.CompletedTask; return Task.CompletedTask;
var guild = (msg.Channel as ITextChannel)?.Guild;
var throwaway = Task.Run(async () => var throwaway = Task.Run(async () =>
{ {
var sw = new Stopwatch(); var sw = new Stopwatch();
sw.Start(); sw.Start();
var t = await _commandService.Execute(usrMsg, usrMsg.Content, MultiMatchHandling.Best);
var t = await ExecuteCommand(usrMsg, usrMsg.Content, guild, usrMsg.Author, MultiMatchHandling.Best);
var command = t.Item1; var command = t.Item1;
var result = t.Item2; var result = t.Item2;
sw.Stop(); sw.Stop();
@ -77,6 +84,67 @@ namespace NadekoBot.Services
return Task.CompletedTask; return Task.CompletedTask;
} }
public async Task<Tuple<Command,IResult>> ExecuteCommand(IUserMessage message, string input, IGuild guild, IUser user, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Best) {
var searchResult = _commandService.Search(message, input);
if (!searchResult.IsSuccess)
return new Tuple<Command, IResult>(null, searchResult);
var commands = searchResult.Commands;
for (int i = commands.Count - 1; i >= 0; i--)
{
var preconditionResult = await commands[i].CheckPreconditions(message);
if (!preconditionResult.IsSuccess)
{
if (commands.Count == 1)
return new Tuple<Command, IResult>(null, searchResult);
else
continue;
}
var parseResult = await commands[i].Parse(message, searchResult, preconditionResult);
if (!parseResult.IsSuccess)
{
if (parseResult.Error == CommandError.MultipleMatches)
{
TypeReaderValue[] argList, paramList;
switch (multiMatchHandling)
{
case MultiMatchHandling.Best:
argList = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray();
paramList = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray();
parseResult = ParseResult.FromSuccess(argList, paramList);
break;
}
}
if (!parseResult.IsSuccess)
{
if (commands.Count == 1)
return new Tuple<Command, IResult>(null, parseResult);
else
continue;
}
}
var cmd = commands[i];
List<Permission> perms;
//check permissions
if (guild != null)
{
using (var uow = DbHandler.UnitOfWork())
{
perms = uow.GuildConfigs.For(guild.Id).Permissions;
}
int index;
if (!perms.CheckPermissions(message, cmd, out index))
return new Tuple<Command, IResult>(null, SearchResult.FromError(CommandError.Exception, $"Permission error. Permission number {index} (`{(index != -1 ? perms[index - 1].GetCommand() : "default")}`)"));
}
return new Tuple<Command, IResult>(commands[i], await commands[i].Execute(message, parseResult));
}
return new Tuple<Command, IResult>(null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload."));
}
} }
public class CommandExecutedEventArgs public class CommandExecutedEventArgs

View File

@ -8,17 +8,25 @@ namespace NadekoBot.Services.Database.Models
{ {
public class Permission : DbEntity public class Permission : DbEntity
{ {
public PermissionType TargetType { get; set; } public PrimaryPermissionType PrimaryTarget { get; set; }
public string Command { get; set; } = null; public ulong PrimaryTargetId { get; set; }
public string Module { get; set; } = null;
public SecondaryPermissionType SecondaryTarget { get; set; }
public string SecondaryTargetName { get; set; }
public bool State { get; set; } public bool State { get; set; }
public string Target { get; set; }
} }
public enum PermissionType public enum PrimaryPermissionType
{ {
User, User,
Channel, Channel,
Role Role
} }
public enum SecondaryPermissionType
{
Module,
Command
}
} }

View File

@ -29,6 +29,7 @@ namespace NadekoBot.Services.Database.Repositories.Impl
public GuildConfig For(ulong guildId) public GuildConfig For(ulong guildId)
{ {
var config = _set.Include(gc => gc.FollowedStreams) var config = _set.Include(gc => gc.FollowedStreams)
.Include(gc => gc.Permissions)
.Include(gc => gc.LogSetting) .Include(gc => gc.LogSetting)
.ThenInclude(ls=>ls.IgnoredChannels) .ThenInclude(ls=>ls.IgnoredChannels)
.FirstOrDefault(c => c.GuildId == guildId); .FirstOrDefault(c => c.GuildId == guildId);