Browse Source

Finish implementing audit logs

Except for InviteUpdateAuditLogData, everything else is implemented, as
I'm not completely sure how to cause an invite update action to occur
right now.
pull/719/head
FiniteReality 8 years ago
parent
commit
aa67a5b209
13 changed files with 346 additions and 45 deletions
  1. +2
    -2
      src/Discord.Net.Rest/API/Common/AuditLog.cs
  2. +16
    -0
      src/Discord.Net.Rest/API/Common/AuditLogWebhook.cs
  3. +8
    -10
      src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs
  4. +82
    -12
      src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildUpdateAuditLogData.cs
  5. +55
    -0
      src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteDeleteAuditLogData.cs
  6. +1
    -5
      src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteCreateAuditLogData.cs
  7. +1
    -6
      src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteDeleteAuditLogData.cs
  8. +1
    -5
      src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteUpdateAuditLogData.cs
  9. +23
    -0
      src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/UnbanAuditLogData.cs
  10. +44
    -0
      src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookCreateAuditLogData.cs
  11. +44
    -0
      src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookDeleteAuditLogData.cs
  12. +68
    -0
      src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookUpdateAuditLogData.cs
  13. +1
    -5
      src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs

+ 2
- 2
src/Discord.Net.Rest/API/Common/AuditLog.cs View File

@@ -5,8 +5,8 @@ namespace Discord.API
internal class AuditLog
{
//TODO: figure out how this works
//[JsonProperty("webhooks")]
//public object Webhooks { get; set; }
[JsonProperty("webhooks")]
public AuditLogWebhook[] Webhooks { get; set; }

[JsonProperty("users")]
public User[] Users { get; set; }


+ 16
- 0
src/Discord.Net.Rest/API/Common/AuditLogWebhook.cs View File

@@ -0,0 +1,16 @@
using Newtonsoft.Json;

namespace Discord.API
{
internal class AuditLogWebhook : User
{
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }

[JsonProperty("guild_id")]
public ulong GuildId { get; set; }

[JsonProperty("token")]
public string Token { get; set; }
}
}

+ 8
- 10
src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs View File

@@ -1,7 +1,4 @@
using System;
using System.Linq;

using Model = Discord.API.AuditLog;
using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;

namespace Discord.Rest
@@ -35,7 +32,7 @@ namespace Discord.Rest
case ActionType.Ban:
return BanAuditLogData.Create(discord, log, entry);
case ActionType.Unban:
break;
return UnbanAuditLogData.Create(discord, log, entry);
case ActionType.MemberUpdated:
return MemberUpdateAuditLogData.Create(discord, log, entry);
case ActionType.MemberRoleUpdated:
@@ -53,14 +50,14 @@ namespace Discord.Rest
case ActionType.InviteUpdated:
break;
case ActionType.InviteDeleted:
break;
return InviteDeleteAuditLogData.Create(discord, log, entry);

case ActionType.WebhookCreated: //50
break;
return WebhookCreateAuditLogData.Create(discord, log, entry);
case ActionType.WebhookUpdated:
break;
return WebhookUpdateAuditLogData.Create(discord, log, entry);
case ActionType.WebhookDeleted:
break;
return WebhookDeleteAuditLogData.Create(discord, log, entry);

case ActionType.EmojiCreated: //60
return EmoteCreateAuditLogData.Create(discord, log, entry);
@@ -71,7 +68,8 @@ namespace Discord.Rest

case ActionType.MessageDeleted: //72
return MessageDeleteAuditLogData.Create(discord, log, entry);
default:

default: //Unknown
return null;
}
return null;


+ 82
- 12
src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/GuildUpdateAuditLogData.cs View File

@@ -1,23 +1,38 @@
using Model = Discord.API.AuditLog;
using System.Linq;

using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;

namespace Discord.Rest
{
public class GuildUpdateAuditLogData : IAuditLogData
{
private GuildUpdateAuditLogData()
{ }
private GuildUpdateAuditLogData(GuildInfo before, GuildInfo after)
{
Before = before;
After = after;
}

internal static GuildUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
{
var changes = entry.Changes;

int? oldAfkTimeout, newAfkTimeout;
DefaultMessageNotifications? oldDefaultMessageNotifications, newDefaultMessageNotifications;
ulong? oldAfkChannelId, newAfkChannelId;
string oldName, newName;
string oldRegionId, newRegionId;
string oldIconHash, newIconHash;
int? oldAfkTimeout = null,
newAfkTimeout = null;
DefaultMessageNotifications? oldDefaultMessageNotifications = null,
newDefaultMessageNotifications = null;
ulong? oldAfkChannelId = null,
newAfkChannelId = null;
string oldName = null,
newName = null;
string oldRegionId = null,
newRegionId = null;
string oldIconHash = null,
newIconHash = null;
VerificationLevel? oldVerificationLevel = null,
newVerificationLevel = null;
ulong? oldOwnerId = null,
newOwnerId = null;

foreach (var change in changes)
{
@@ -47,12 +62,67 @@ namespace Discord.Rest
oldIconHash = change.OldValue?.ToObject<string>();
newIconHash = change.NewValue?.ToObject<string>();
break;
//TODO: owner, verification level
case "verification_level":
oldVerificationLevel = change.OldValue?.ToObject<VerificationLevel>();
newVerificationLevel = change.NewValue?.ToObject<VerificationLevel>();
break;
case "owner":
oldOwnerId = change.OldValue?.ToObject<ulong>();
newOwnerId = change.NewValue?.ToObject<ulong>();
break;
//TODO: 2fa auth, explicit content filter
}
}

//TODO: implement this
return null;
IUser oldOwner = null;
if (oldOwnerId != null)
{
var oldOwnerInfo = log.Users.FirstOrDefault(x => x.Id == oldOwnerId.Value);
oldOwner = RestUser.Create(discord, oldOwnerInfo);
}

IUser newOwner = null;
if (newOwnerId != null)
{
var newOwnerInfo = log.Users.FirstOrDefault(x => x.Id == newOwnerId.Value);
newOwner = RestUser.Create(discord, newOwnerInfo);
}

var before = new GuildInfo(oldAfkTimeout, oldDefaultMessageNotifications,
oldAfkChannelId, oldName, oldRegionId, oldIconHash, oldVerificationLevel, oldOwner);
var after = new GuildInfo(newAfkTimeout, newDefaultMessageNotifications,
newAfkChannelId, newName, newRegionId, newIconHash, newVerificationLevel, newOwner);

return new GuildUpdateAuditLogData(before, after);
}

public GuildInfo Before { get; }
public GuildInfo After { get; }

public struct GuildInfo
{
internal GuildInfo(int? afkTimeout, DefaultMessageNotifications? defaultNotifs,
ulong? afkChannel, string name, string region, string icon,
VerificationLevel? verification, IUser owner)
{
AfkTimeout = afkTimeout;
DefaultMessageNotifications = defaultNotifs;
AfkChannelId = afkChannel;
Name = name;
RegionId = region;
IconHash = icon;
VerificationLevel = verification;
Owner = owner;
}

public int? AfkTimeout { get; }
public DefaultMessageNotifications? DefaultMessageNotifications { get; }
public ulong? AfkChannelId { get; }
public string Name { get; }
public string RegionId { get; }
public string IconHash { get; }
public VerificationLevel? VerificationLevel { get; }
public IUser Owner { get; }
}
}
}

+ 55
- 0
src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/InviteDeleteAuditLogData.cs View File

@@ -0,0 +1,55 @@
using System.Linq;

using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;

namespace Discord.Rest
{
public class InviteDeleteAuditLogData : IAuditLogData
{
private InviteDeleteAuditLogData(int maxAge, string code, bool temporary, IUser inviter, ulong channelId, int uses, int maxUses)
{
MaxAge = maxAge;
Code = code;
Temporary = temporary;
Creator = inviter;
ChannelId = channelId;
Uses = uses;
MaxUses = maxUses;
}

internal static InviteDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
{
var changes = entry.Changes;

var maxAgeModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_age");
var codeModel = changes.FirstOrDefault(x => x.ChangedProperty == "code");
var temporaryModel = changes.FirstOrDefault(x => x.ChangedProperty == "temporary");
var inviterIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "inviter_id");
var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id");
var usesModel = changes.FirstOrDefault(x => x.ChangedProperty == "uses");
var maxUsesModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_uses");

var maxAge = maxAgeModel.OldValue.ToObject<int>();
var code = codeModel.OldValue.ToObject<string>();
var temporary = temporaryModel.OldValue.ToObject<bool>();
var inviterId = inviterIdModel.OldValue.ToObject<ulong>();
var channelId = channelIdModel.OldValue.ToObject<ulong>();
var uses = usesModel.OldValue.ToObject<int>();
var maxUses = maxUsesModel.OldValue.ToObject<int>();

var inviterInfo = log.Users.FirstOrDefault(x => x.Id == inviterId);
var inviter = RestUser.Create(discord, inviterInfo);

return new InviteDeleteAuditLogData(maxAge, code, temporary, inviter, channelId, uses, maxUses);
}

public int MaxAge { get; }
public string Code { get; }
public bool Temporary { get; }
public IUser Creator { get; }
public ulong ChannelId { get; } //TODO: IChannel-ify
public int Uses { get; }
public int MaxUses { get; }
}
}

+ 1
- 5
src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteCreateAuditLogData.cs View File

@@ -27,11 +27,7 @@ namespace Discord.Rest
var id = entry.Options.OverwriteTargetId.Value;
var type = entry.Options.OverwriteType;

PermissionTarget target;
if (type == "member")
target = PermissionTarget.User;
else
target = PermissionTarget.Role;
PermissionTarget target = type == "member" ? PermissionTarget.User : PermissionTarget.Role;

return new OverwriteCreateAuditLogData(new Overwrite(id, target, permissions));
}


+ 1
- 6
src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteDeleteAuditLogData.cs View File

@@ -32,12 +32,7 @@ namespace Discord.Rest
var id = idModel.OldValue.ToObject<ulong>();
var allow = allowModel.OldValue.ToObject<ulong>();

PermissionTarget target;

if (type == "member")
target = PermissionTarget.User;
else
target = PermissionTarget.Role;
PermissionTarget target = type == "member" ? PermissionTarget.User : PermissionTarget.Role;

return new OverwriteDeleteAuditLogData(new Overwrite(id, target, new OverwritePermissions(allow, deny)));
}


+ 1
- 5
src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/OverwriteUpdateAuditLogData.cs View File

@@ -30,11 +30,7 @@ namespace Discord.Rest
var beforePermissions = new OverwritePermissions(beforeAllow ?? 0, beforeDeny ?? 0);
var afterPermissions = new OverwritePermissions(afterAllow ?? 0, afterDeny ?? 0);

PermissionTarget target;
if (entry.Options.OverwriteType == "member")
target = PermissionTarget.User;
else
target = PermissionTarget.Role;
PermissionTarget target = entry.Options.OverwriteType == "member" ? PermissionTarget.User : PermissionTarget.Role;

return new OverwriteUpdateAuditLogData(beforePermissions, afterPermissions, entry.Options.OverwriteTargetId.Value, target);
}


+ 23
- 0
src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/UnbanAuditLogData.cs View File

@@ -0,0 +1,23 @@
using System.Linq;

using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;

namespace Discord.Rest
{
public class UnbanAuditLogData : IAuditLogData
{
private UnbanAuditLogData(IUser user)
{
Target = user;
}

internal static UnbanAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
{
var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId);
return new UnbanAuditLogData(RestUser.Create(discord, userInfo));
}

public IUser Target { get; }
}
}

+ 44
- 0
src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookCreateAuditLogData.cs View File

@@ -0,0 +1,44 @@
using System.Linq;

using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;

namespace Discord.Rest
{
public class WebhookCreateAuditLogData : IAuditLogData
{
private WebhookCreateAuditLogData(IWebhookUser user, string token, string name, ulong channelId)
{
Webhook = user;
Token = token;
Name = name;
ChannelId = channelId;
}

internal static WebhookCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
{
var changes = entry.Changes;

var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id");
var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type");
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");

var channelId = channelIdModel.NewValue.ToObject<ulong>();
var type = typeModel.NewValue.ToObject<int>(); //TODO: what on *earth* is this for
var name = nameModel.NewValue.ToObject<string>();

var webhookInfo = log.Webhooks?.FirstOrDefault(x => x.Id == entry.TargetId);
var userInfo = RestWebhookUser.Create(discord, null, webhookInfo, entry.TargetId.Value);

return new WebhookCreateAuditLogData(userInfo, webhookInfo.Token, name, channelId);
}

//Corresponds to the *current* data
public IWebhookUser Webhook { get; }
public string Token { get; }

//Corresponds to the *audit log* data
public string Name { get; }
public ulong ChannelId { get; }
}
}

+ 44
- 0
src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookDeleteAuditLogData.cs View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;

namespace Discord.Rest
{
public class WebhookDeleteAuditLogData : IAuditLogData
{
private WebhookDeleteAuditLogData(ulong id, ulong channel, string name, string avatar)
{
WebhookId = id;
ChannelId = channel;
Name = name;
Avatar = avatar;
}

internal static WebhookDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
{
var changes = entry.Changes;

var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id");
var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type");
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");
var avatarHashModel = changes.FirstOrDefault(x => x.ChangedProperty == "avatar_hash");

var channelId = channelIdModel.OldValue.ToObject<ulong>();
var type = typeModel.OldValue.ToObject<int>();
var name = nameModel.OldValue.ToObject<string>();
var avatarHash = avatarHashModel?.OldValue?.ToObject<string>();

return new WebhookDeleteAuditLogData(entry.TargetId.Value, channelId, name, avatarHash);
}

public ulong WebhookId { get; }
public ulong ChannelId { get; }
public string Name { get; }
public string Avatar { get; }
}
}

+ 68
- 0
src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/WebhookUpdateAuditLogData.cs View File

@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Model = Discord.API.AuditLog;
using EntryModel = Discord.API.AuditLogEntry;

namespace Discord.Rest
{
public class WebhookUpdateAuditLogData : IAuditLogData
{
private WebhookUpdateAuditLogData(IWebhookUser user, string token, WebhookInfo before, WebhookInfo after)
{
Webhook = user;
Token = token;
Before = before;
After = after;
}

internal static WebhookUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
{
var changes = entry.Changes;

var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");
var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id");
var avatarHashModel = changes.FirstOrDefault(x => x.ChangedProperty == "avatar_hash");

var oldName = nameModel?.OldValue?.ToObject<string>();
var oldChannelId = channelIdModel?.OldValue?.ToObject<ulong>();
var oldAvatar = avatarHashModel?.OldValue?.ToObject<string>();
var before = new WebhookInfo(oldName, oldChannelId, oldAvatar);

var newName = nameModel?.NewValue?.ToObject<string>();
var newChannelId = channelIdModel?.NewValue?.ToObject<ulong>();
var newAvatar = avatarHashModel?.NewValue?.ToObject<string>();
var after = new WebhookInfo(newName, newChannelId, newAvatar);

var webhookInfo = log.Webhooks?.FirstOrDefault(x => x.Id == entry.TargetId);
var userInfo = RestWebhookUser.Create(discord, null, webhookInfo, entry.TargetId.Value);

return new WebhookUpdateAuditLogData(userInfo, webhookInfo.Token, before, after);
}

//Again, the *current* data
public IWebhookUser Webhook { get; }
public string Token { get; }

//And the *audit log* data
public WebhookInfo Before { get; }
public WebhookInfo After { get; }

public struct WebhookInfo
{
internal WebhookInfo(string name, ulong? channelId, string avatar)
{
Name = name;
ChannelId = channelId;
Avatar = avatar;
}

public string Name { get; }
public ulong? ChannelId { get; }
public string Avatar { get; }
}
}
}

+ 1
- 5
src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs View File

@@ -11,12 +11,8 @@ namespace Discord.Rest
: base(discord, model.Id)
{
Action = model.Action;

if (model.Changes != null)
Data = AuditLogHelper.CreateData(discord, fullLog, model);

Data = AuditLogHelper.CreateData(discord, fullLog, model);
User = user;

Reason = model.Reason;
}



Loading…
Cancel
Save