Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Nullinside.Api.Common/Nullinside.Api.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="log4net" Version="2.0.17" />
<PackageReference Include="log4net" Version="2.0.17"/>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
<PackageReference Include="SSH.NET" Version="2024.2.0" />
<PackageReference Include="SSH.NET" Version="2024.2.0"/>
<PackageReference Include="TwitchLib.Api" Version="3.9.0"/>
<PackageReference Include="TwitchLib.Client" Version="3.3.1"/>
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Nullinside.Api.Common/Twitch/ITwitchApiProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public interface ITwitchApiProxy {
/// The Twitch access token. These are the credentials used for all requests.
/// </summary>
TwitchAccessToken? OAuth { get; set; }

/// <summary>
/// The Twitch app configuration. These are used for all requests.
/// </summary>
Expand Down
46 changes: 26 additions & 20 deletions src/Nullinside.Api.Common/Twitch/TwitchApiProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class TwitchApiProxy : ITwitchApiProxy {
/// Initializes a new instance of the <see cref="TwitchApiProxy" /> class.
/// </summary>
public TwitchApiProxy() {
TwitchAppConfig = new() {
TwitchAppConfig = new TwitchAppConfig {
ClientId = Environment.GetEnvironmentVariable("TWITCH_BOT_CLIENT_ID"),
ClientSecret = Environment.GetEnvironmentVariable("TWITCH_BOT_CLIENT_SECRET"),
ClientRedirect = Environment.GetEnvironmentVariable("TWITCH_BOT_CLIENT_REDIRECT")
Expand All @@ -46,21 +46,27 @@ public TwitchApiProxy() {
/// <param name="token">The access token.</param>
/// <param name="refreshToken">The refresh token.</param>
/// <param name="tokenExpires">When the token expires (utc).</param>
/// <param name="clientId">The client id of the registered twitch app, uses environment variable
/// "TWITCH_BOT_CLIENT_ID" when null.</param>
/// <param name="clientSecret">The client secret of the registered twitch app, uses environment variable
/// "TWITCH_BOT_CLIENT_SECRET" when null.</param>
/// <param name="clientRedirect">The url to redirect to from the registered twitch app, uses environment variable
/// "TWITCH_BOT_CLIENT_REDIRECT" when null.</param>
public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires, string? clientId = null,
/// <param name="clientId">
/// The client id of the registered twitch app, uses environment variable
/// "TWITCH_BOT_CLIENT_ID" when null.
/// </param>
/// <param name="clientSecret">
/// The client secret of the registered twitch app, uses environment variable
/// "TWITCH_BOT_CLIENT_SECRET" when null.
/// </param>
/// <param name="clientRedirect">
/// The url to redirect to from the registered twitch app, uses environment variable
/// "TWITCH_BOT_CLIENT_REDIRECT" when null.
/// </param>
public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires, string? clientId = null,
string? clientSecret = null, string? clientRedirect = null) {
OAuth = new TwitchAccessToken {
AccessToken = token,
RefreshToken = refreshToken,
ExpiresUtc = tokenExpires
};
TwitchAppConfig = new() {

TwitchAppConfig = new TwitchAppConfig {
ClientId = clientId ?? Environment.GetEnvironmentVariable("TWITCH_BOT_CLIENT_ID"),
ClientSecret = clientSecret ?? Environment.GetEnvironmentVariable("TWITCH_BOT_CLIENT_SECRET"),
ClientRedirect = clientRedirect ?? Environment.GetEnvironmentVariable("TWITCH_BOT_CLIENT_REDIRECT")
Expand All @@ -74,14 +80,14 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires,

/// <inheritdoc />
public virtual TwitchAccessToken? OAuth { get; set; }

/// <inheritdoc />
public virtual TwitchAppConfig? TwitchAppConfig { get; set; }

/// <inheritdoc />
public virtual async Task<TwitchAccessToken?> CreateAccessToken(string code, CancellationToken token = new()) {
ITwitchAPI api = GetApi();
AuthCodeResponse? response = await api.Auth.GetAccessTokenFromCodeAsync(code, TwitchAppConfig?.ClientSecret,
AuthCodeResponse? response = await api.Auth.GetAccessTokenFromCodeAsync(code, TwitchAppConfig?.ClientSecret,
TwitchAppConfig?.ClientRedirect);
if (null == response) {
return null;
Expand All @@ -101,7 +107,7 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires,
if (string.IsNullOrWhiteSpace(TwitchAppConfig?.ClientSecret) || string.IsNullOrWhiteSpace(TwitchAppConfig?.ClientId)) {
return null;
}

ITwitchAPI api = GetApi();
RefreshResponse? response = await api.Auth.RefreshAuthTokenAsync(OAuth?.RefreshToken, TwitchAppConfig?.ClientSecret, TwitchAppConfig?.ClientId);
if (null == response) {
Expand Down Expand Up @@ -145,7 +151,7 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires,
}

/// <inheritdoc />
public virtual async Task<string?> GetUserEmail(CancellationToken token = new()) {
public virtual async Task<string?> GetUserEmail(CancellationToken token = new()) {
return await Retry.Execute(async () => {
ITwitchAPI api = GetApi();
GetUsersResponse? response = await api.Helix.Users.GetUsersAsync();
Expand All @@ -158,7 +164,7 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires,
}

/// <inheritdoc />
public virtual async Task<IEnumerable<TwitchModeratedChannel>> GetUserModChannels(string userId) {
public virtual async Task<IEnumerable<TwitchModeratedChannel>> GetUserModChannels(string userId) {
using var client = new HttpClient();

var ret = new List<TwitchModeratedChannel>();
Expand Down Expand Up @@ -189,7 +195,7 @@ public virtual async Task<IEnumerable<TwitchModeratedChannel>> GetUserModChanne
}

/// <inheritdoc />
public virtual async Task<IEnumerable<BannedUser>> BanChannelUsers(string channelId, string botId,
public virtual async Task<IEnumerable<BannedUser>> BanChannelUsers(string channelId, string botId,
IEnumerable<(string Id, string Username)> users, string reason, CancellationToken token = new()) {
return await Retry.Execute(async () => {
ITwitchAPI api = GetApi();
Expand Down Expand Up @@ -223,7 +229,7 @@ public virtual async Task<IEnumerable<BannedUser>> BanChannelUsers(string chann
}

/// <inheritdoc />
public virtual async Task<IEnumerable<Chatter>> GetChannelUsers(string channelId, string botId,
public virtual async Task<IEnumerable<Chatter>> GetChannelUsers(string channelId, string botId,
CancellationToken token = new()) {
return await Retry.Execute(async () => {
ITwitchAPI api = GetApi();
Expand All @@ -247,7 +253,7 @@ public virtual async Task<IEnumerable<Chatter>> GetChannelUsers(string channelI
}

/// <inheritdoc />
public virtual async Task<IEnumerable<string>> GetChannelsLive(IEnumerable<string> userIds) {
public virtual async Task<IEnumerable<string>> GetChannelsLive(IEnumerable<string> userIds) {
ITwitchAPI api = GetApi();

// We can only query 100 at a time, so throttle the search.
Expand All @@ -271,7 +277,7 @@ public virtual async Task<IEnumerable<string>> GetChannelsLive(IEnumerable<stri
}

/// <inheritdoc />
public virtual async Task<IEnumerable<Moderator>> GetChannelMods(string channelId, CancellationToken token = new()) {
public virtual async Task<IEnumerable<Moderator>> GetChannelMods(string channelId, CancellationToken token = new()) {
return await Retry.Execute(async () => {
ITwitchAPI api = GetApi();

Expand All @@ -298,7 +304,7 @@ public virtual async Task<IEnumerable<string>> GetChannelsLive(IEnumerable<stri
}

/// <inheritdoc />
public virtual async Task<bool> AddChannelMod(string channelId, string userId, CancellationToken token = new()) {
public virtual async Task<bool> AddChannelMod(string channelId, string userId, CancellationToken token = new()) {
return await Retry.Execute(async () => {
ITwitchAPI api = GetApi();
await api.Helix.Moderation.AddChannelModeratorAsync(channelId, userId);
Expand Down
12 changes: 6 additions & 6 deletions src/Nullinside.Api.Common/Twitch/TwitchAppConfig.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
namespace Nullinside.Api.Common.Twitch;

/// <summary>
/// The configuration for a twitch app that provides OAuth tokens.
/// The configuration for a twitch app that provides OAuth tokens.
/// </summary>
public class TwitchAppConfig {
/// <summary>
/// The client id.
/// The client id.
/// </summary>
public string? ClientId { get; set; }

/// <summary>
/// The client secret.
/// The client secret.
/// </summary>
public string? ClientSecret { get; set; }

/// <summary>
/// A registered URL that the Twitch API is allowed to redirect to on our website.
/// A registered URL that the Twitch API is allowed to redirect to on our website.
/// </summary>
public string? ClientRedirect { get; set; }
}
5 changes: 5 additions & 0 deletions src/Nullinside.Api.Model/Ddl/User.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.ComponentModel.DataAnnotations;

using Microsoft.EntityFrameworkCore;

namespace Nullinside.Api.Model.Ddl;
Expand Down Expand Up @@ -60,6 +62,7 @@ public class User : ITableModel {
/// <summary>
/// The last timestamp of when the user logged into the site.
/// </summary>
[Timestamp]
public DateTime UpdatedOn { get; set; }

/// <summary>
Expand Down Expand Up @@ -92,6 +95,8 @@ public void OnModelCreating(ModelBuilder modelBuilder) {
.HasMaxLength(255);
entity.Property(e => e.Token)
.HasMaxLength(255);
entity.Property(e => e.UpdatedOn)
.IsRowVersion();
// TODO: Add the other strings in this file with lengths
});
}
Expand Down
Loading