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

Include VerifiedEmailForPluginPublish feature flag #45

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
15 changes: 13 additions & 2 deletions PluginBuilder/Controllers/AdminController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ FROM versions
{
var plugin = new AdminPluginViewModel
{
ProjectSlug = row.slug, Visibility = row.visibility, PublisherEmail = row.email
ProjectSlug = row.slug,
Visibility = row.visibility,
PublisherEmail = row.email
};

if (row.ver != null)
Expand All @@ -55,10 +57,19 @@ FROM versions

plugins.Add(plugin);
}
return View(new AdminPluginSettingViewModel { Plugins = plugins, VerifiedEmailForPluginPublish = await conn.GetVerifiedEmailForPluginPublishSetting() });
}

return View(plugins);
[HttpPost]
public async Task<IActionResult> UpdateVerifiedEmailRequirement(bool verifiedEmailForPluginPublish)
{
await using var conn = await connectionFactory.Open();
await conn.UpdateVerifiedEmailForPluginPublishSetting(verifiedEmailForPluginPublish);
TempData[TempDataConstant.SuccessMessage] = $"Email requirement setting for publishing plugin updated successfully";
return RedirectToAction("ListPlugins");
}


// Plugin Edit
[HttpGet("plugins/edit/{slug}")]
public async Task<IActionResult> PluginEdit(string slug)
Expand Down
23 changes: 18 additions & 5 deletions PluginBuilder/Controllers/PluginController.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
using Microsoft.AspNetCore.Authorization;
using Dapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PluginBuilder.Components.PluginVersion;
using PluginBuilder.ModelBinders;
using PluginBuilder.Services;
using PluginBuilder.ViewModels;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using PluginBuilder.Components.PluginVersion;

namespace PluginBuilder.Controllers
{
[Authorize(Policy = Policies.OwnPlugin)]
[Route("/plugins/{pluginSlug}")]
public class PluginController(
DBConnectionFactory connectionFactory,
UserManager<IdentityUser> userManager,
BuildService buildService,
EmailService emailService,
EventAggregator eventAggregator)
: Controller
{
private DBConnectionFactory ConnectionFactory { get; } = connectionFactory;
private UserManager<IdentityUser> UserManager { get; } = userManager;
private BuildService BuildService { get; } = buildService;
private EventAggregator EventAggregator { get; } = eventAggregator;

Expand Down Expand Up @@ -103,7 +107,16 @@ public async Task<IActionResult> CreateBuild(
{
if (!ModelState.IsValid)
return View(model);
await using var conn = await ConnectionFactory.Open();
await using var conn = await connectionFactory.Open();
var user = await UserManager.GetUserAsync(User);
var emailSettings = await emailService.GetEmailSettingsFromDb();
var needToVerifyEmail = emailSettings?.PasswordSet == true && !await UserManager.IsEmailConfirmedAsync(user!);
var isEmailVerificationFeatureEnabled = await conn.GetVerifiedEmailForPluginPublishSetting();
if (isEmailVerificationFeatureEnabled && needToVerifyEmail)
{
TempData[TempDataConstant.WarningMessage] = "You need to verify your email address to complete the plugin build process";
return RedirectToAction("AccountDetails", "Account");
}
var buildId = await conn.NewBuild(pluginSlug, model.ToBuildParameter());
_ = BuildService.Build(new FullBuildId(pluginSlug, buildId));
return RedirectToAction(nameof(Build), new { pluginSlug = pluginSlug.ToString(), buildId });
Expand Down
19 changes: 19 additions & 0 deletions PluginBuilder/NpgsqlConnectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,5 +230,24 @@ DELETE FROM settings
""";
return connection.ExecuteAsync(query, new { key });
}

public static async Task<bool> GetVerifiedEmailForPluginPublishSetting(this NpgsqlConnection connection)
{
var settingValue = await connection.QuerySingleOrDefaultAsync<string>("SELECT value FROM settings WHERE key = 'VerifiedEmailForPluginPublish'");
if (settingValue == null)
{
await connection.ExecuteAsync("INSERT INTO settings (key, value) VALUES ('VerifiedEmailForPluginPublish', 'true')");
settingValue = "true";
}
return bool.TryParse(settingValue, out var result) && result;
}

public static async Task UpdateVerifiedEmailForPluginPublishSetting(this NpgsqlConnection connection, bool newValue)
{
var stringValue = newValue.ToString().ToLower();
await connection.ExecuteAsync("UPDATE settings SET value = @Value WHERE key = 'VerifiedEmailForPluginPublish'",
new { Value = stringValue });
}

}
}
6 changes: 6 additions & 0 deletions PluginBuilder/ViewModels/Admin/AdminPluginViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ public class AdminPluginViewModel
public string PublisherEmail { get; set; }
public PluginVisibilityEnum Visibility { get; set; }
}

public class AdminPluginSettingViewModel
{
public IEnumerable<AdminPluginViewModel> Plugins { get; set; }
public bool VerifiedEmailForPluginPublish { get; set; }
}
102 changes: 58 additions & 44 deletions PluginBuilder/Views/Admin/ListPlugins.cshtml
Original file line number Diff line number Diff line change
@@ -1,54 +1,68 @@
@model IEnumerable<AdminPluginViewModel>
@model AdminPluginSettingViewModel
@{
Layout = "_Layout";
ViewData.SetActivePage(AdminNavPages.Plugins, "Plugins");
}

<div class="d-sm-flex align-items-center justify-content-between">
<h2 class="mb-4">@ViewData["Title"]</h2>
@{
var nonPreReleasePublishers = Model.Where(m => !m.PreRelease && !string.IsNullOrEmpty(m.Version)).Select(m => m.PublisherEmail).ToList();
}
@if (nonPreReleasePublishers.Any())
{
<a asp-controller="Admin" asp-action="EmailSender" asp-route-to="@string.Join(",", nonPreReleasePublishers)" class="btn btn-primary">
Email all Publishers
</a>
}
</div>
<div class="d-flex flex-column flex-md-row align-items-center justify-content-between gap-3 my-4">
<h2 class="mb-3 mb-md-0">@ViewData["Title"]</h2>

<div class="d-flex flex-column flex-sm-row align-items-center gap-3">
<div class="d-flex align-items-center">
<form asp-controller="Admin" asp-action="UpdateVerifiedEmailRequirement" method="post" class="d-flex align-items-center">
<input type="checkbox" class="btcpay-toggle me-2" id="featureToggle" asp-for="@Model.VerifiedEmailForPluginPublish"
onchange="this.form.submit()" />
<label class="form-check-label text-wrap" for="featureToggle">
Require Verified Email for publishing
</label>
</form>
</div>

<table class="table">
<thead>
<tr>
<th>Project Slug</th>
<th>Version</th>
<th>Build ID</th>
<th>BTCPay Min Version</th>
<th>Pre-Release</th>
<th>Updated At</th>
<th>Publisher Email</th>
<th>Visibility</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var plugin in Model)
@if (Model.Plugins.Where(m => !m.PreRelease && !string.IsNullOrEmpty(m.Version)).Any())
{
<a asp-controller="Admin" asp-action="EmailSender"
asp-route-to="@string.Join(",", Model.Plugins.Where(m => !m.PreRelease && !string.IsNullOrEmpty(m.Version)).Select(m => m.PublisherEmail))"
class="btn btn-primary">
Email Publishers
</a>
}
</div>
</div>


<div class="table-responsive">
<table class="table">
<thead>
<tr>
<td>@plugin.ProjectSlug</td>
<td>@plugin.Version</td>
<td>@plugin.BuildId</td>
<td>@plugin.BtcPayMinVer</td>
<td>@plugin.PreRelease</td>
<td>@plugin.UpdatedAt</td>
<td>@plugin.PublisherEmail</td>
<td>@plugin.Visibility</td>
<td>
<a asp-controller="Admin" asp-action="PluginEdit" asp-route-slug="@plugin.ProjectSlug">Edit</a> |
<a asp-controller="Admin" asp-action="PluginDelete" asp-route-slug="@plugin.ProjectSlug">Delete</a>
</td>
<th>Project Slug</th>
<th>Version</th>
<th>Build ID</th>
<th>BTCPay Min Version</th>
<th>Pre-Release</th>
<th>Updated At</th>
<th>Publisher Email</th>
<th>Visibility</th>
<th></th>
</tr>
}
</tbody>
</table>
</thead>
<tbody>
@foreach (var plugin in Model.Plugins)
{
<tr>
<td>@plugin.ProjectSlug</td>
<td>@plugin.Version</td>
<td>@plugin.BuildId</td>
<td>@plugin.BtcPayMinVer</td>
<td>@plugin.PreRelease</td>
<td>@plugin.UpdatedAt</td>
<td>@plugin.PublisherEmail</td>
<td>@plugin.Visibility</td>
<td>
<a asp-controller="Admin" asp-action="PluginEdit" asp-route-slug="@plugin.ProjectSlug">Edit</a> |
<a asp-controller="Admin" asp-action="PluginDelete" asp-route-slug="@plugin.ProjectSlug">Delete</a>
</td>
</tr>
}
</tbody>
</table>
</div>