Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relay Server to simplify Twitch configuration #405

Merged
merged 19 commits into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
2c5330b
Began work on relay server
csharpfritz Mar 8, 2024
2ffec96
Applying formatting changes through GitHub Actions
github-actions[bot] Mar 8, 2024
8137b14
Removed Common requirement, started URL
csharpfritz Mar 10, 2024
fa061de
Built redirect service to host Twitch interaction
csharpfritz Mar 10, 2024
dda10c2
Applying formatting changes through GitHub Actions
github-actions[bot] Mar 10, 2024
93bfcfc
Completed first pass at profile pic relay
csharpfritz Mar 12, 2024
6a1d9e6
Merge branch 'feature_TwitchRelay' of github.com:csharpfritz/TagzApp …
csharpfritz Mar 12, 2024
cf8d7fe
Applying formatting changes through GitHub Actions
github-actions[bot] Mar 12, 2024
2d83bf4
Fixed auth enforcement on the ModalCustomization page
csharpfritz Mar 12, 2024
2aa2a75
Began connecting TwitchRelay
csharpfritz Mar 12, 2024
ca0c338
Added missing Using statements
csharpfritz Mar 12, 2024
8458054
Updates
csharpfritz Mar 14, 2024
37e7d99
Updated Moderator policy
csharpfritz Mar 14, 2024
8a7631d
Now building the Blazor application directly
csharpfritz Mar 14, 2024
4c7d039
Merge branch 'main' into feature_TwitchRelay
csharpfritz Mar 14, 2024
3ea924e
Completed connecting UserProfile pics and the login storage for chat
csharpfritz Mar 14, 2024
09b8ee2
Applying formatting changes through GitHub Actions
github-actions[bot] Mar 14, 2024
1773eb3
Merge branch 'feature_TwitchRelay' of github.com:csharpfritz/TagzApp …
csharpfritz Mar 15, 2024
7e560ac
First pass and GitHub action to deploy TwitchRelay
csharpfritz Mar 15, 2024
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
51 changes: 51 additions & 0 deletions .github/workflows/TagzAppTwitchRelay.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Build and deploy .NET Core application to Function App TagzAppTwitchRelay
on:
push:
branches: [main]
paths: ["src/TagzApp.TwitchRelay/**"]
env:
AZURE_FUNCTIONAPP_NAME: TagzAppTwitchRelay
AZURE_FUNCTIONAPP_PACKAGE_PATH: TagzApp.TwitchRelay/published
CONFIGURATION: Release
DOTNET_CORE_VERSION: 8.0.x
WORKING_DIRECTORY: src/TagzApp.TwitchRelay
DOTNET_CORE_VERSION_INPROC: 6.0.x
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET SDK
uses: actions/setup-dotnet@v3
with:
dotnet-version: ${{ env.DOTNET_CORE_VERSION }}
- name: Setup .NET Core (for inproc extensions)
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ env.DOTNET_CORE_VERSION_INPROC }}
- name: Restore
run: dotnet restore "${{ env.WORKING_DIRECTORY }}"
- name: Build
run: dotnet build "${{ env.WORKING_DIRECTORY }}" --configuration ${{ env.CONFIGURATION }} --no-restore
- name: Publish
run: dotnet publish "${{ env.WORKING_DIRECTORY }}" --configuration ${{ env.CONFIGURATION }} --no-build --output "${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}"
- name: Publish Artifacts
uses: actions/upload-artifact@v3
with:
name: functionapp
path: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v3
with:
name: functionapp
path: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
- name: Deploy to Azure Function App
uses: Azure/functions-action@v1
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
publish-profile: ${{ secrets.TagzAppTwitchRelay_2EC9 }}
package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
4 changes: 2 additions & 2 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ jobs:
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
run: dotnet build TagzApp.Blazor --no-restore
- name: Unit Test
run: dotnet test --no-build --verbosity normal
run: dotnet test --verbosity normal
working-directory: ./src/TagzApp.UnitTest

#playwright:
Expand Down
3 changes: 3 additions & 0 deletions scripts/startTwitchRelay
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
cd ../src/TagzApp.TwitchRelay
func start --cors http://localhost:5000 --port 7082 --csharp
4 changes: 2 additions & 2 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project>

<ItemGroup>
<!-- <ItemGroup>
<Using Include="TagzApp.Common" />
<Using Include="TagzApp.Common.Models" />
</ItemGroup>
</ItemGroup> -->

</Project>
Original file line number Diff line number Diff line change
@@ -1,31 +1,47 @@
@using System.ComponentModel.DataAnnotations
@inject HttpClient Http
@inject NavigationManager NavMgr
@inject IConfiguration Config

<UiProviderConfig ProviderName="TwitchChat" Health="@Health" ProviderIconCssClass="bi-twitch">

<EditForm Model="Model" OnValidSubmit="SaveConfig">
<AntiforgeryToken />
<ValidationSummary />

<div class="alert-primary" style="padding: 4px;">
<p>To configure the Twitch chat provider you will connect to a custom relay server managed by the TagzApp team.
You will log into Twitch and your TagzApp installation will be updated with the appropriate configuration for
your login to access Twitch.
</p>
<p>None of your personal data or credentials are stored on the relay server.</p>
</div>

<dl>
<dt><label for="ClientId">Client Id:</label></dt>
<dd>
<InputText name="ClientId" @bind-Value="Model.ClientId" placeholder="Twitch Client Id" />
<ValidationMessage For="() => Model.ClientId" class="text-danger" />
</dd>
<dt><label for="ClientSecret">Client Secret:</label></dt>
<dd>
<InputText type="password" name="ClientSecret" @bind-Value="Model.ClientSecret" placeholder="Twitch Client Secret" />
<ValidationMessage For="() => Model.ClientSecret" class="text-danger" />
</dd>
<dt><label for="ChatBotName">Chat Bot Name:</label></dt>
<dd>
<InputText name="ChatBotName" @bind-Value="Model.ChatBotName" placeholder="Twitch Chat Bot Name" />
<ValidationMessage For="() => Model.ChatBotName" class="text-danger" />
@if (string.IsNullOrEmpty(Model.ChatBotName) && !string.IsNullOrEmpty(LoginUrl))
{
<span>Not connected to Twitch</span> <a href="@LoginUrl" target="_blank">Click to login to Twitch</a>
}
else if (string.IsNullOrEmpty(Model.ChatBotName) && string.IsNullOrEmpty(LoginUrl))
{
<span class="alert-danger">Unable to connect to Twitch</span>
}
else
{
<span>@Model.ChatBotName (Connected)</span>

@if (string.IsNullOrEmpty(LoginUrl))
{
<span class="alert-danger" style="margin-left: 2em;">Unable to connect to Twitch</span>
}
else {
<a href="@LoginUrl" target="_blank" style="margin-left: 2em;">Click to change Twitch accounts</a>
}
}
</dd>
<dt><label for="OAuthToken">OAuth Token:</label></dt>
<dd>
<InputText type="password" name="OAuthToken" @bind-Value="Model.OAuthToken" placeholder="Twitch OAuth Token" />
<ValidationMessage For="() => Model.OAuthToken" class="text-danger" />
</dd>
<dt><label for="ChannelName">Channel Name:</label></dt>
<dt><label for="ChannelName">Channel Name:</label></dt>
<dd>
<InputText name="ChannelName" @bind-Value="Model.ChannelName" placeholder="Twitch Channel Name" />
<ValidationMessage For="() => Model.ChannelName" class="text-danger" />
Expand All @@ -49,18 +65,37 @@

public (SocialMediaStatus Status, string Message) Health { get; set; } = (SocialMediaStatus.Unknown, string.Empty);

public string LoginUrl { get; set; } = "";

public ViewModel Model { get; set; } = new();

protected override async Task OnInitializedAsync()
{

// Twitch Relay URI
var twitchRelayUri = new Uri(new Uri(Config["TwitchRelayUri"]), "/api/GetLoginUrl");

try
{
var returnToUri = new Uri(new Uri(NavMgr.BaseUri), "/Admin/TwitchRelay");
var result = await Http.GetAsync($"{twitchRelayUri}?returnto={returnToUri}");
LoginUrl = await result.Content.ReadAsStringAsync();
} catch
{
LoginUrl = string.Empty;
}

await base.OnInitializedAsync();
}


protected override async Task OnParametersSetAsync()
{

var providerConfiguration = await Provider.GetConfiguration(ConfigureTagzAppFactory.Current);

Model = new ViewModel
{
ClientId = providerConfiguration.GetConfigurationByKey("ClientId"),
ClientSecret = providerConfiguration.GetConfigurationByKey("ClientSecret"),
{
ChatBotName = providerConfiguration.GetConfigurationByKey("ChatBotName"),
OAuthToken = providerConfiguration.GetConfigurationByKey("OAuthToken"),
ChannelName = providerConfiguration.GetConfigurationByKey("ChannelName"),
Expand All @@ -78,8 +113,6 @@

var providerConfiguration = await Provider.GetConfiguration(ConfigureTagzAppFactory.Current);

providerConfiguration.SetConfigurationByKey("ClientId", Model.ClientId);
providerConfiguration.SetConfigurationByKey("ClientSecret", Model.ClientSecret);
providerConfiguration.SetConfigurationByKey("ChatBotName", Model.ChatBotName);
providerConfiguration.SetConfigurationByKey("OAuthToken", Model.OAuthToken);
providerConfiguration.SetConfigurationByKey("ChannelName", Model.ChannelName);
Expand All @@ -94,12 +127,6 @@

// add properties for each of the fields you want to edit

[Required]
public string ClientId { get; set; }

[Required]
public string ClientSecret { get; set; }

[Required]
public string ChatBotName { get; set; } = string.Empty;

Expand Down
2 changes: 2 additions & 0 deletions src/TagzApp.Blazor.Client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

var builder = WebAssemblyHostBuilder.CreateDefault(args);

builder.Services.AddScoped<HttpClient>();

builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddSingleton<AuthenticationStateProvider, PersistentAuthenticationStateProvider>();
Expand Down
5 changes: 5 additions & 0 deletions src/TagzApp.Blazor.Client/TagzApp.Blazor.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<Using Include="TagzApp.Common" />
<Using Include="TagzApp.Common.Models" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TagzApp.Common\TagzApp.Common.csproj" />
<ProjectReference Include="..\TagzApp.Components\TagzApp.Components.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@page "/admin/modalcustomization"

@attribute [Authorize(Policy=RolesAndPolicies.Policy.AdminRoleOnly)]
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Authorization
@using System.Drawing
Expand Down Expand Up @@ -111,14 +111,16 @@
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;

protected override Task OnInitializedAsync()
protected override Task OnParametersSetAsync()
{
/*
var user = HttpContext.User;
if (!user.IsInRole("Admin"))
{
NavigationManager.NavigateTo("/");
}
return base.OnInitializedAsync();
*/
return base.OnParametersSetAsync();
}

async Task SaveChanges()
Expand Down
1 change: 1 addition & 0 deletions src/TagzApp.Blazor/Components/Admin/Pages/Providers.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@page "/admin/providers"
@attribute [Authorize(Roles = RolesAndPolicies.Role.Admin)]
@rendermode InteractiveServer
@using System.Reflection
@layout Admin.Shared.AdminLayout
Expand Down
52 changes: 52 additions & 0 deletions src/TagzApp.Blazor/Components/Admin/Pages/TwitchRelayReceive.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
@page "/Admin/TwitchRelay"
@inject IMessagingService messagingService

@if (TwitchProvider is null) {
<div class="alert alert-danger" role="alert">Unable to connect to the Twitch Chat provider</div>
}
else
{
<div class="alert alert-primary" role="alert">
Connecting TwitchChat with bot name @User
</div>
}

@code {

[Parameter, SupplyParameterFromQuery(Name="access_token")]
public string Access_Token { get; set; }

[Parameter, SupplyParameterFromQuery(Name="user")]
public string User { get; set; }

private ISocialMediaProvider TwitchProvider { get; set; }

private IProviderConfiguration Configuration { get; set; }

protected override async Task OnInitializedAsync()
{

// Get the Twitch provider and then its configuration
TwitchProvider = messagingService.Providers.FirstOrDefault(p => p.Id == "TWITCH");
if (TwitchProvider is null) return;

Configuration = await TwitchProvider.GetConfiguration(ConfigureTagzAppFactory.Current);

await base.OnInitializedAsync();
}

protected override async Task OnParametersSetAsync()
{

if (TwitchProvider is null) return;

// Update the Twitch configuration with the AccessToken and chat bot name returned
Configuration.SetConfigurationByKey("ChatBotName", User);
Configuration.SetConfigurationByKey("OAuthToken", Access_Token);

await TwitchProvider.SaveConfiguration(ConfigureTagzAppFactory.Current, Configuration);

}


}
1 change: 1 addition & 0 deletions src/TagzApp.Blazor/Components/_Imports.razor
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
Expand Down
2 changes: 1 addition & 1 deletion src/TagzApp.Blazor/Service_Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public static async Task<IServiceCollection> AddTagzAppSecurity(this IServiceCol
{
config.AddPolicy(RolesAndPolicies.Policy.AdminRoleOnly, policy => { policy.RequireRole(RolesAndPolicies.Role.Admin); });
config.AddPolicy(RolesAndPolicies.Policy.Moderator,
policy => { policy.RequireAuthenticatedUser(); });
policy => { policy.RequireRole(RolesAndPolicies.Role.Moderator, RolesAndPolicies.Role.Admin); });
});

return services;
Expand Down
5 changes: 5 additions & 0 deletions src/TagzApp.Blazor/TagzApp.Blazor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
</PropertyGroup>
</Target>

<ItemGroup>
<Using Include="TagzApp.Common" />
<Using Include="TagzApp.Common.Models" />
</ItemGroup>

<ItemGroup>
<Content Remove="Components\FirstStartRouting.razor" />
</ItemGroup>
Expand Down
5 changes: 4 additions & 1 deletion src/TagzApp.Blazor/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
"AppConfigProvider": "Postgres",
"AppConfigConnection": "Server=localhost;Port=5432;Database=postgres;User Id=tagz;Password=tagz;"
},
// When debugging and working locally with TwitchRelay, use a local instance.
// Comment this out to use the production instance
"TwitchRelayUri": "http://localhost:7082",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"DetailedErrors": true
}
}
3 changes: 2 additions & 1 deletion src/TagzApp.Blazor/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"Microsoft.AspNetCore": "Warning"
}
},
"TwitchRelayUri": "https://twitchrelay.tagzapp.net",
"AllowedHosts": "*"

}
}
5 changes: 5 additions & 0 deletions src/TagzApp.Common/TagzApp.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
<InternalsVisibleTo Include="TagzApp.UnitTest" />
</ItemGroup>

<ItemGroup>
<Using Include="TagzApp.Common" />
<Using Include="TagzApp.Common.Models" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.24" />
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="8.0.0" />
Expand Down
5 changes: 5 additions & 0 deletions src/TagzApp.Communication/TagzApp.Communication.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<Using Include="TagzApp.Common" />
<Using Include="TagzApp.Common.Models" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Ensure.That" Version="11.0.0-p3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
Expand Down
Loading
Loading