Compare commits
227 Commits
Author | SHA1 | Date | |
---|---|---|---|
ec0a5377b3 | |||
b876da069d | |||
f06063d7eb | |||
c6ba4f4bee | |||
89da4ab2a1 | |||
99ac0a3cab | |||
a964c30705 | |||
2334d0297d | |||
e444c6bcf0 | |||
601582fc98 | |||
e939dbe24e | |||
143ad85fd5 | |||
20377e9789 | |||
e4a24df7b4 | |||
e88ca00658 | |||
2312c612d7 | |||
3aee52482d | |||
32248e0be6 | |||
6c18c320bd | |||
e31f32e5aa | |||
a856390566 | |||
64b8291487 | |||
2ebd1310c9 | |||
09118fcb42 | |||
5d5167abbc | |||
bf43dea060 | |||
6ebab830c5 | |||
9a9a78e0bd | |||
418eff7d21 | |||
d39869ca8e | |||
7829168ea7 | |||
dd83e3ee67 | |||
c3ac0e365d | |||
2986625605 | |||
8beaeabf09 | |||
fa9b4b6112 | |||
d81fbe4585 | |||
536c044139 | |||
376531195e | |||
abf4ff71d7 | |||
d25debcea3 | |||
948c186cb5 | |||
ba27e70fe3 | |||
c93d2576af | |||
e0b0156640 | |||
a3ca6a3071 | |||
b20157450b | |||
7e4f0923d7 | |||
e0c2b2982f | |||
9a231c28af | |||
94a02b7bf9 | |||
22c8fb411a | |||
cf46210ff8 | |||
f32d988297 | |||
7fe4577158 | |||
8985dcb4c0 | |||
d346444c51 | |||
ef27a0d6b0 | |||
627158cb5d | |||
648edcabba | |||
0f34c6efc5 | |||
cc3cc55269 | |||
a503a9d5bc | |||
789baf99ff | |||
036279a54c | |||
481f18cf1c | |||
2f1e386554 | |||
1e0c7cf43d | |||
7978c89731 | |||
82221f54c5 | |||
2e23e6e4d5 | |||
3a79fa074a | |||
696c63c6d2 | |||
8f6dc52430 | |||
c8a9ad9807 | |||
a0933d07d8 | |||
6bf61e2008 | |||
36ecc55578 | |||
47065299ca | |||
0f707a7607 | |||
7590c5550f | |||
3d23a5c79a | |||
9aa0374dc2 | |||
058a191673 | |||
5fbb9160f1 | |||
2c3dad0592 | |||
00f039d31e | |||
497ef1750b | |||
7d4cd04ce9 | |||
04c0b9d37d | |||
b9c16c0727 | |||
0a30f2b7e8 | |||
dbb1d53202 | |||
2c88f36e3d | |||
d91dcad774 | |||
6eb4ea2a2d | |||
ff6187c336 | |||
1253dfe0c8 | |||
c1f2f9a970 | |||
8d5e7ed69f | |||
3d3540f090 | |||
61f1fcb99c | |||
c7b576d6d3 | |||
ab3b1d5e46 | |||
ddff3faba9 | |||
f7bb8444da | |||
92128974bb | |||
4eb15d4806 | |||
39cb3780c8 | |||
81030f468b | |||
2032cb1ace | |||
5e4c91440e | |||
13bbad863f | |||
3065ed5094 | |||
9eb75cfff0 | |||
9305c99577 | |||
9078da6937 | |||
4c579639b9 | |||
b86472ab52 | |||
5e1ac485a0 | |||
527c1a12f4 | |||
ef4e99b3a7 | |||
12a9635309 | |||
78adb24a75 | |||
49955cf642 | |||
af3b289331 | |||
d11591e5aa | |||
9c6174e3f2 | |||
09c2f74d52 | |||
7d7e0254cb | |||
fe767afe9c | |||
3378f0e4ee | |||
c0341798ea | |||
fc114dc5db | |||
7107d844e1 | |||
59af0a817e | |||
9615eded85 | |||
c51fa23fcb | |||
8737fd6f1e | |||
0f109ab93a | |||
63df2742db | |||
7b7811f8ad | |||
80f74b9939 | |||
1f29f77f66 | |||
dd7da5f354 | |||
49b30da697 | |||
90ed767d75 | |||
7871f0f3ce | |||
a60cf40a3c | |||
f4eb2f6726 | |||
cfe87a802e | |||
6c90ec812f | |||
196d611c1c | |||
ff41cb2735 | |||
fb11674301 | |||
b9e7f4530c | |||
27049687bf | |||
13503edc63 | |||
d33f82d969 | |||
177632eee0 | |||
ca0de5258e | |||
1de788bc26 | |||
2b41909d47 | |||
e23a9f22dd | |||
465b7850b7 | |||
a0f2eedd7f | |||
8605e3ca5a | |||
dd893e6d48 | |||
c4cd1a5a54 | |||
94152651fc | |||
563ea76192 | |||
4913fab0b3 | |||
b49d011edf | |||
6e04281b03 | |||
f2df8e96db | |||
c6dd7605b2 | |||
71dd00da0f | |||
da48ca884d | |||
8c6c66fb11 | |||
f333b57310 | |||
d1d00e6c98 | |||
52300e680a | |||
b3f7353582 | |||
7db6b82a1a | |||
a50a13374f | |||
3952fe5a72 | |||
2e61a43e4f | |||
ebe03e9310 | |||
11dd3ce110 | |||
1919c24959 | |||
aa80f31e52 | |||
6d8400e72f | |||
fa8d0c91fc | |||
e91ff95712 | |||
0883a8dbff | |||
0db297d1cd | |||
db73052ee5 | |||
8b95069610 | |||
2a12744cd5 | |||
1df4059284 | |||
475894b680 | |||
1663bf8e52 | |||
ffca1d2486 | |||
eb876845ff | |||
02c134bf4b | |||
af55c11aa0 | |||
33bc6adcb5 | |||
56e4dcc11e | |||
467cf7620e | |||
85ac8dd701 | |||
1f2ad4e884 | |||
cf2d9af664 | |||
7a105047e9 | |||
bc8bdef37d | |||
fd0519b955 | |||
d5ffb56fa8 | |||
d6cce9e2d8 | |||
08ec46637f | |||
f596795792 | |||
2c56bfd4aa | |||
755615da30 | |||
4cc0060c67 | |||
52af015c2f | |||
eae6d13284 | |||
2a20a7cf21 | |||
27251005ec | |||
90a9b2e5a1 |
@ -55,7 +55,7 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="connectionstring" HelpText="Enter a complete connection string including all parameters and delimiters" ResourceKey="ConnectionString">String:</Label>
|
<Label Class="col-sm-3" For="connectionstring" HelpText="Enter a complete connection string including all parameters and delimiters" ResourceKey="ConnectionString">Settings:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<textarea id="connectionstring" class="form-control" @bind="@_connectionString" rows="3"></textarea>
|
<textarea id="connectionstring" class="form-control" @bind="@_connectionString" rows="3"></textarea>
|
||||||
</div>
|
</div>
|
||||||
@ -77,7 +77,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordType" class="form-control" @bind="@_hostPassword" autocomplete="new-password" />
|
<input id="password" type="@_passwordType" class="form-control" @bind="@_hostPassword" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglePassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglePassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -86,7 +86,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_confirmPasswordType" class="form-control" @bind="@_confirmPassword" autocomplete="new-password" />
|
<input id="confirm" type="@_confirmPasswordType" class="form-control" @bind="@_confirmPassword" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@ToggleConfirmPassword">@_toggleConfirmPassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@ToggleConfirmPassword" tabindex="-1">@_toggleConfirmPassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,10 +4,12 @@
|
|||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
@if (_pages != null)
|
||||||
|
{
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@foreach (var p in _pages)
|
@foreach (var p in _pages)
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
{
|
{
|
||||||
string url = NavigateUrl(p.Path);
|
string url = NavigateUrl(p.Path);
|
||||||
<div class="col-md-2 mx-auto text-center mb-3">
|
<div class="col-md-2 mx-auto text-center mb-3">
|
||||||
@ -18,18 +20,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<Page> _pages;
|
private List<Page> _pages;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin");
|
var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin");
|
||||||
if (admin != null)
|
if (admin != null)
|
||||||
{
|
{
|
||||||
_pages = PageState.Pages.Where(item => item.ParentId == admin?.PageId).ToList();
|
_pages = PageState.Pages.Where(item => item.ParentId == admin.PageId).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,8 +62,7 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<Label Class="col-sm-3" For="permissions" HelpText="Select the permissions you want for the folder" ResourceKey="Permissions">Permissions: </Label>
|
<Label Class="col-sm-3" For="permissions" HelpText="Select the permissions you want for the folder" ResourceKey="Permissions">Permissions: </Label>
|
||||||
<PermissionGrid EntityName="@EntityNames.Folder" PermissionNames="@(PermissionNames.Browse + "," + PermissionNames.View + "," + PermissionNames.Edit)" Permissions="@_permissions" @ref="_permissionGrid" />
|
<PermissionGrid EntityName="@EntityNames.Folder" PermissionNames="@(PermissionNames.Browse + "," + PermissionNames.View + "," + PermissionNames.Edit)" PermissionList="@_permissions" @ref="_permissionGrid" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -99,7 +98,7 @@
|
|||||||
private string _imagesizes = string.Empty;
|
private string _imagesizes = string.Empty;
|
||||||
private string _capacity = "0";
|
private string _capacity = "0";
|
||||||
private bool _isSystem;
|
private bool _isSystem;
|
||||||
private string _permissions = string.Empty;
|
private List<Permission> _permissions = null;
|
||||||
private string _createdBy;
|
private string _createdBy;
|
||||||
private DateTime _createdOn;
|
private DateTime _createdOn;
|
||||||
private string _modifiedBy;
|
private string _modifiedBy;
|
||||||
@ -131,7 +130,7 @@
|
|||||||
_imagesizes = folder.ImageSizes;
|
_imagesizes = folder.ImageSizes;
|
||||||
_capacity = folder.Capacity.ToString();
|
_capacity = folder.Capacity.ToString();
|
||||||
_isSystem = folder.IsSystem;
|
_isSystem = folder.IsSystem;
|
||||||
_permissions = folder.Permissions;
|
_permissions = folder.PermissionList;
|
||||||
_createdBy = folder.CreatedBy;
|
_createdBy = folder.CreatedBy;
|
||||||
_createdOn = folder.CreatedOn;
|
_createdOn = folder.CreatedOn;
|
||||||
_modifiedBy = folder.ModifiedBy;
|
_modifiedBy = folder.ModifiedBy;
|
||||||
@ -196,7 +195,7 @@
|
|||||||
folder.ImageSizes = _imagesizes;
|
folder.ImageSizes = _imagesizes;
|
||||||
folder.Capacity = int.Parse(_capacity);
|
folder.Capacity = int.Parse(_capacity);
|
||||||
folder.IsSystem = _isSystem;
|
folder.IsSystem = _isSystem;
|
||||||
folder.Permissions = _permissionGrid.GetPermissions();
|
folder.PermissionList = _permissionGrid.GetPermissionList();
|
||||||
|
|
||||||
if (_folderId != -1)
|
if (_folderId != -1)
|
||||||
{
|
{
|
||||||
|
@ -20,15 +20,6 @@ else
|
|||||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="translated" HelpText="Specify If You Wish To Select Languages That Have Translations Installed" ResourceKey="Translated">Translated?</Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="translated" class="form-select" value="@_translated" @onchange="(e => TranslatedChanged(e))" required>
|
|
||||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
|
||||||
<option value="False">@SharedLocalizer["No"]</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="name" HelpText="Name Of The Language" ResourceKey="Name">Name:</Label>
|
<Label Class="col-sm-3" For="name" HelpText="Name Of The Language" ResourceKey="Name">Name:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="_code" class="form-select" @bind="@_code" required>
|
<select id="_code" class="form-select" @bind="@_code" required>
|
||||||
@ -57,13 +48,12 @@ else
|
|||||||
<TabPanel Name="Upload" ResourceKey="Upload" Security="SecurityAccessLevel.Host">
|
<TabPanel Name="Upload" ResourceKey="Upload" Security="SecurityAccessLevel.Host">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" HelpText="Upload one or more translations. Once they are uploaded click Install to complete the installation." ResourceKey="LanguageUpload">Translation: </Label>
|
<Label Class="col-sm-3" HelpText="Upload one or more translations. Once they are uploaded click Install." ResourceKey="LanguageUpload">Translation: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" />
|
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" OnUpload="OnUpload" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-success" @onclick="InstallTranslations">@SharedLocalizer["Install"]</button>
|
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabStrip>
|
</TabStrip>
|
||||||
@ -73,7 +63,6 @@ else
|
|||||||
private ElementReference form;
|
private ElementReference form;
|
||||||
private bool validated = false;
|
private bool validated = false;
|
||||||
|
|
||||||
private string _translated = "True";
|
|
||||||
private string _code = "-";
|
private string _code = "-";
|
||||||
private string _default = "False";
|
private string _default = "False";
|
||||||
private List<string> _languages;
|
private List<string> _languages;
|
||||||
@ -91,18 +80,11 @@ else
|
|||||||
|
|
||||||
private async Task LoadCultures()
|
private async Task LoadCultures()
|
||||||
{
|
{
|
||||||
_cultures = await LocalizationService.GetCulturesAsync(bool.Parse(_translated));
|
_cultures = await LocalizationService.GetCulturesAsync(false);
|
||||||
_cultures = _cultures.Where(c => !c.Name.Equals(Constants.DefaultCulture) && !_languages.Contains(c.Name));
|
_cultures = _cultures.Where(c => !c.Name.Equals(Constants.DefaultCulture) && !_languages.Contains(c.Name));
|
||||||
_code = "-";
|
_code = "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void TranslatedChanged(ChangeEventArgs e)
|
|
||||||
{
|
|
||||||
_translated = (string)e.Value;
|
|
||||||
await LoadCultures();
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveLanguage()
|
private async Task SaveLanguage()
|
||||||
{
|
{
|
||||||
validated = true;
|
validated = true;
|
||||||
@ -142,19 +124,6 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InstallTranslations()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await PackageService.InstallPackagesAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Language.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Installing Translations");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SetCultureAsync(string culture)
|
private async Task SetCultureAsync(string culture)
|
||||||
{
|
{
|
||||||
if (culture != CultureInfo.CurrentUICulture.Name)
|
if (culture != CultureInfo.CurrentUICulture.Name)
|
||||||
@ -166,4 +135,9 @@ else
|
|||||||
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnUpload()
|
||||||
|
{
|
||||||
|
AddModuleMessage(string.Format(Localizer["Success.Language.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,23 +35,27 @@ else
|
|||||||
{
|
{
|
||||||
<td>@((string.IsNullOrEmpty(context.Version)) ? "---" : context.Version)</td>
|
<td>@((string.IsNullOrEmpty(context.Version)) ? "---" : context.Version)</td>
|
||||||
<td>
|
<td>
|
||||||
@switch (TranslationAvailable(context.Code, context.Version))
|
@{
|
||||||
|
var translation = TranslationAvailable(context.Code, context.Version);
|
||||||
|
}
|
||||||
|
@if (translation != null)
|
||||||
{
|
{
|
||||||
case "install":
|
if (string.IsNullOrEmpty(context.Version))
|
||||||
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(context.Code))>@SharedLocalizer["Download"]</button>
|
{
|
||||||
break;
|
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(context.Code, translation.Version))>@SharedLocalizer["Download"]</button>
|
||||||
case "upgrade":
|
}
|
||||||
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(context.Code))>@SharedLocalizer["Upgrade"]</button>
|
else
|
||||||
break;
|
{
|
||||||
|
if (Version.Parse(translation.Version).CompareTo(Version.Parse(context.Version)) > 0)
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(context.Code, translation.Version))>@SharedLocalizer["Upgrade"]</button>
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host) && _install)
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-success" @onclick="InstallTranslations">@SharedLocalizer["Install"]</button>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (_package != null)
|
@if (_package != null)
|
||||||
@ -98,7 +102,6 @@ else
|
|||||||
private List<Language> _languages;
|
private List<Language> _languages;
|
||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private Package _package;
|
private Package _package;
|
||||||
private bool _install = false;
|
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||||
|
|
||||||
@ -134,38 +137,16 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string TranslationAvailable(string code, string version)
|
private Package TranslationAvailable(string code, string version)
|
||||||
{
|
{
|
||||||
if (_packages != null)
|
return _packages?.FirstOrDefault(item => item.PackageId == (Constants.PackageId + "." + code));
|
||||||
{
|
|
||||||
var package = _packages.Where(item => item.PackageId == (Constants.PackageId + "." + code)).FirstOrDefault();
|
|
||||||
if (package != null)
|
|
||||||
{
|
|
||||||
// package version needs to match current framework version
|
|
||||||
if (Version.Parse(package.Version).CompareTo(Version.Parse(Constants.Version)) == 0)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(version))
|
|
||||||
{
|
|
||||||
return "install";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0)
|
|
||||||
{
|
|
||||||
return "upgrade";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task GetPackage(string code)
|
private async Task GetPackage(string code, string version)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_package = await PackageService.GetPackageAsync(Constants.PackageId + "." + code, Constants.Version);
|
_package = await PackageService.GetPackageAsync(Constants.PackageId + "." + code, version);
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -181,9 +162,8 @@ else
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Language Package {Name} {Version} Downloaded Successfully", _package.PackageId, _package.Version);
|
await logger.LogInformation("Language Package {Name} {Version} Downloaded Successfully", _package.PackageId, _package.Version);
|
||||||
AddModuleMessage(Localizer["Success.Language.Download"], MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Language.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_package = null;
|
_package = null;
|
||||||
_install = true;
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -198,19 +178,4 @@ else
|
|||||||
_package = null;
|
_package = null;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InstallTranslations()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await PackageService.InstallPackagesAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Translation.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
|
||||||
_install = false;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Installing Translations");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
@using System.Net
|
||||||
@namespace Oqtane.Modules.Admin.Login
|
@namespace Oqtane.Modules.Admin.Login
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@ -33,7 +34,7 @@
|
|||||||
<Label Class="control-label" For="password" HelpText="Please enter your Password" ResourceKey="Password">Password:</Label>
|
<Label Class="control-label" For="password" HelpText="Please enter your Password" ResourceKey="Password">Password:</Label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" name="Password" class="form-control" placeholder="@Localizer["Password.Placeholder"]" @bind="@_password" required />
|
<input id="password" type="@_passwordtype" name="Password" class="form-control" placeholder="@Localizer["Password.Placeholder"]" @bind="@_password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group mt-2">
|
<div class="form-group mt-2">
|
||||||
@ -205,7 +206,7 @@
|
|||||||
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider
|
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider
|
||||||
.GetService(typeof(IdentityAuthenticationStateProvider));
|
.GetService(typeof(IdentityAuthenticationStateProvider));
|
||||||
authstateprovider.NotifyAuthenticationChanged();
|
authstateprovider.NotifyAuthenticationChanged();
|
||||||
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, true));
|
NavigationManager.NavigateTo(NavigateUrl(WebUtility.UrlDecode(_returnUrl), true));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -106,12 +106,6 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// external link to log item will display Details component
|
|
||||||
if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int id))
|
|
||||||
{
|
|
||||||
NavigationManager.NavigateTo(EditUrl(PageState.Page.Path, ModuleState.ModuleId, "Detail", $"/{id}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UrlParameters.ContainsKey("level"))
|
if (UrlParameters.ContainsKey("level"))
|
||||||
{
|
{
|
||||||
_level = UrlParameters["level"];
|
_level = UrlParameters["level"];
|
||||||
@ -241,4 +235,15 @@ else
|
|||||||
_page = page;
|
_page = page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
// external link to log item will display Details component
|
||||||
|
if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int id))
|
||||||
|
{
|
||||||
|
NavigationManager.NavigateTo(EditUrl(PageState.Page.Path, ModuleState.ModuleId, "Detail", $"/{id}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ else
|
|||||||
private bool IsValid(string name)
|
private bool IsValid(string name)
|
||||||
{
|
{
|
||||||
// must contain letters, underscores and digits and first character must be letter or underscore
|
// must contain letters, underscores and digits and first character must be letter or underscore
|
||||||
return !string.IsNullOrEmpty(name) && name.ToLower() != "module" && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
|
return !string.IsNullOrEmpty(name) && name.ToLower() != "module" && !name.ToLower().Contains("oqtane") && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TemplateChanged(ChangeEventArgs e)
|
private void TemplateChanged(ChangeEventArgs e)
|
||||||
|
@ -65,13 +65,15 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
<br />
|
||||||
|
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Upload" ResourceKey="Upload">
|
<TabPanel Name="Upload" ResourceKey="Upload">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" HelpText="Upload one or more module packages. Once they are uploaded click Install to complete the installation." ResourceKey="Module">Module: </Label>
|
<Label Class="col-sm-3" HelpText="Upload one or more module packages. Once they are uploaded click Install to complete the installation." ResourceKey="Module">Module: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" />
|
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" OnUpload="OnUpload" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -111,13 +113,8 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button type="button" class="btn btn-success" @onclick="InstallModules">@SharedLocalizer["Install"]</button>
|
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private string _price = "free";
|
private string _price = "free";
|
||||||
@ -236,7 +233,7 @@
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_packageid, _packageversion, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_packageid, _packageversion, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _packageversion);
|
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _packageversion);
|
||||||
AddModuleMessage(Localizer["Success.Module.Download"], MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Module.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_productname = "";
|
_productname = "";
|
||||||
_packagelicense = "";
|
_packagelicense = "";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
@ -248,16 +245,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InstallModules()
|
private void OnUpload()
|
||||||
{
|
{
|
||||||
try
|
AddModuleMessage(string.Format(Localizer["Success.Module.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
{
|
|
||||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Installing Modules");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@
|
|||||||
private bool IsValid(string name)
|
private bool IsValid(string name)
|
||||||
{
|
{
|
||||||
// must contain letters, underscores and digits and first character must be letter or underscore
|
// must contain letters, underscores and digits and first character must be letter or underscore
|
||||||
return !string.IsNullOrEmpty(name) && name.ToLower() != "module" && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
|
return !string.IsNullOrEmpty(name) && name.ToLower() != "module" && !name.ToLower().Contains("oqtane") && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TemplateChanged(ChangeEventArgs e)
|
private void TemplateChanged(ChangeEventArgs e)
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
@inject IStringLocalizer<Edit> Localizer
|
@inject IStringLocalizer<Edit> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
@if (_initialized)
|
||||||
|
{
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Definition" ResourceKey="Definition">
|
<TabPanel Name="Definition" ResourceKey="Definition">
|
||||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
@ -95,9 +97,10 @@
|
|||||||
<TabPanel Name="Permissions" ResourceKey="Permissions">
|
<TabPanel Name="Permissions" ResourceKey="Permissions">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<PermissionGrid EntityName="@EntityNames.ModuleDefinition" PermissionNames="@PermissionNames.Utilize" Permissions="@_permissions" @ref="_permissionGrid" />
|
<PermissionGrid EntityName="@EntityNames.ModuleDefinition" PermissionNames="@PermissionNames.Utilize" PermissionList="@_permissions" @ref="_permissionGrid" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<br />
|
||||||
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
|
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
@ -128,10 +131,6 @@
|
|||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
@if (_install)
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-success" @onclick="InstallTranslations">@SharedLocalizer["Install"]</button>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -190,8 +189,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
private ElementReference form;
|
private ElementReference form;
|
||||||
private bool validated = false;
|
private bool validated = false;
|
||||||
private int _moduleDefinitionId;
|
private int _moduleDefinitionId;
|
||||||
@ -206,7 +207,7 @@
|
|||||||
private string _contact = "";
|
private string _contact = "";
|
||||||
private string _license = "";
|
private string _license = "";
|
||||||
private string _runtimes = "";
|
private string _runtimes = "";
|
||||||
private string _permissions;
|
private List<Permission> _permissions = null;
|
||||||
private string _createdby;
|
private string _createdby;
|
||||||
private DateTime _createdon;
|
private DateTime _createdon;
|
||||||
private string _modifiedby;
|
private string _modifiedby;
|
||||||
@ -219,7 +220,6 @@
|
|||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private List<Language> _languages;
|
private List<Language> _languages;
|
||||||
private Package _package;
|
private Package _package;
|
||||||
private bool _install = false;
|
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||||
|
|
||||||
@ -242,7 +242,7 @@
|
|||||||
_contact = moduleDefinition.Contact;
|
_contact = moduleDefinition.Contact;
|
||||||
_license = moduleDefinition.License;
|
_license = moduleDefinition.License;
|
||||||
_runtimes = moduleDefinition.Runtimes;
|
_runtimes = moduleDefinition.Runtimes;
|
||||||
_permissions = moduleDefinition.Permissions;
|
_permissions = moduleDefinition.PermissionList;
|
||||||
_createdby = moduleDefinition.CreatedBy;
|
_createdby = moduleDefinition.CreatedBy;
|
||||||
_createdon = moduleDefinition.CreatedOn;
|
_createdon = moduleDefinition.CreatedOn;
|
||||||
_modifiedby = moduleDefinition.ModifiedBy;
|
_modifiedby = moduleDefinition.ModifiedBy;
|
||||||
@ -262,6 +262,8 @@
|
|||||||
}
|
}
|
||||||
_languages = _languages.OrderBy(item => item.Name).ToList();
|
_languages = _languages.OrderBy(item => item.Name).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -278,6 +280,9 @@
|
|||||||
if (await interop.FormValid(form))
|
if (await interop.FormValid(form))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
var moduleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||||
|
if (!moduleDefinitions.Any(item => item.Name.ToLower() == _name.ToLower() && item.ModuleDefinitionId != _moduleDefinitionId))
|
||||||
{
|
{
|
||||||
var moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId);
|
var moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId);
|
||||||
if (moduledefinition.Name != _name)
|
if (moduledefinition.Name != _name)
|
||||||
@ -292,10 +297,15 @@
|
|||||||
{
|
{
|
||||||
moduledefinition.Categories = _categories;
|
moduledefinition.Categories = _categories;
|
||||||
}
|
}
|
||||||
moduledefinition.Permissions = _permissionGrid.GetPermissions();
|
moduledefinition.PermissionList = _permissionGrid.GetPermissionList();
|
||||||
await ModuleDefinitionService.UpdateModuleDefinitionAsync(moduledefinition);
|
await ModuleDefinitionService.UpdateModuleDefinitionAsync(moduledefinition);
|
||||||
await logger.LogInformation("ModuleDefinition Saved {ModuleDefinition}", moduledefinition);
|
await logger.LogInformation("ModuleDefinition Saved {ModuleDefinition}", moduledefinition);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.DuplicateName"], MessageType.Warning);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -359,9 +369,8 @@
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _package.PackageId, _package.Version);
|
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _package.PackageId, _package.Version);
|
||||||
AddModuleMessage(Localizer["Success.Translation.Download"], MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Translation.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_package = null;
|
_package = null;
|
||||||
_install = true;
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -370,19 +379,4 @@
|
|||||||
AddModuleMessage(Localizer["Error.Translation.Download"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.Translation.Download"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InstallTranslations()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await PackageService.InstallPackagesAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Translation.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
|
||||||
_install = false;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Installing Translations");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,6 @@ else
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
|
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
|
||||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
<select id="page" class="form-select" @bind="@_pageId" required>
|
<select id="page" class="form-select" @bind="@_pageId" required>
|
||||||
@foreach (Page p in PageState.Pages)
|
@foreach (Page p in PageState.Pages)
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
{
|
{
|
||||||
<option value="@p.PageId">@(new string('-', p.Level * 2))@(p.Name)</option>
|
<option value="@p.PageId">@(new string('-', p.Level * 2))@(p.Name)</option>
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@
|
|||||||
{
|
{
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<PermissionGrid EntityName="@EntityNames.Module" PermissionNames="@_permissionNames" Permissions="@_permissions" @ref="_permissionGrid" />
|
<PermissionGrid EntityName="@EntityNames.Module" PermissionNames="@_permissionNames" PermissionList="@_permissions" @ref="_permissionGrid" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -101,7 +101,7 @@
|
|||||||
private string _containerType;
|
private string _containerType;
|
||||||
private string _allPages = "false";
|
private string _allPages = "false";
|
||||||
private string _permissionNames = "";
|
private string _permissionNames = "";
|
||||||
private string _permissions = null;
|
private List<Permission> _permissions = null;
|
||||||
private string _pageId;
|
private string _pageId;
|
||||||
private PermissionGrid _permissionGrid;
|
private PermissionGrid _permissionGrid;
|
||||||
private Type _moduleSettingsType;
|
private Type _moduleSettingsType;
|
||||||
@ -123,7 +123,7 @@
|
|||||||
_containers = ThemeService.GetContainerControls(_themes, PageState.Page.ThemeType);
|
_containers = ThemeService.GetContainerControls(_themes, PageState.Page.ThemeType);
|
||||||
_containerType = ModuleState.ContainerType;
|
_containerType = ModuleState.ContainerType;
|
||||||
_allPages = ModuleState.AllPages.ToString();
|
_allPages = ModuleState.AllPages.ToString();
|
||||||
_permissions = ModuleState.Permissions;
|
_permissions = ModuleState.PermissionList;
|
||||||
_pageId = ModuleState.PageId.ToString();
|
_pageId = ModuleState.PageId.ToString();
|
||||||
createdby = ModuleState.CreatedBy;
|
createdby = ModuleState.CreatedBy;
|
||||||
createdon = ModuleState.CreatedOn;
|
createdon = ModuleState.CreatedOn;
|
||||||
@ -207,7 +207,7 @@
|
|||||||
var module = ModuleState;
|
var module = ModuleState;
|
||||||
module.AllPages = bool.Parse(_allPages);
|
module.AllPages = bool.Parse(_allPages);
|
||||||
module.PageModuleId = ModuleState.PageModuleId;
|
module.PageModuleId = ModuleState.PageModuleId;
|
||||||
module.Permissions = _permissionGrid.GetPermissions();
|
module.PermissionList = _permissionGrid.GetPermissionList();
|
||||||
await ModuleService.UpdateModuleAsync(module);
|
await ModuleService.UpdateModuleAsync(module);
|
||||||
|
|
||||||
if (_moduleSettingsType != null)
|
if (_moduleSettingsType != null)
|
||||||
|
@ -183,7 +183,7 @@
|
|||||||
private string _themetype = string.Empty;
|
private string _themetype = string.Empty;
|
||||||
private string _containertype = string.Empty;
|
private string _containertype = string.Empty;
|
||||||
private string _icon = string.Empty;
|
private string _icon = string.Empty;
|
||||||
private string _permissions = string.Empty;
|
private string _permissions = null;
|
||||||
private PermissionGrid _permissionGrid;
|
private PermissionGrid _permissionGrid;
|
||||||
private Type _themeSettingsType;
|
private Type _themeSettingsType;
|
||||||
private object _themeSettings;
|
private object _themeSettings;
|
||||||
@ -202,7 +202,6 @@
|
|||||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||||
_containertype = PageState.Site.DefaultContainerType;
|
_containertype = PageState.Site.DefaultContainerType;
|
||||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||||
_permissions = string.Empty;
|
|
||||||
ThemeSettings();
|
ThemeSettings();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -222,7 +221,7 @@
|
|||||||
{
|
{
|
||||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == null))
|
foreach (Page p in PageState.Pages.Where(item => item.ParentId == null))
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
{
|
{
|
||||||
_children.Add(p);
|
_children.Add(p);
|
||||||
}
|
}
|
||||||
@ -232,7 +231,7 @@
|
|||||||
{
|
{
|
||||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid)))
|
foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid)))
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
{
|
{
|
||||||
_children.Add(p);
|
_children.Add(p);
|
||||||
}
|
}
|
||||||
@ -378,7 +377,7 @@
|
|||||||
page.DefaultContainerType = string.Empty;
|
page.DefaultContainerType = string.Empty;
|
||||||
}
|
}
|
||||||
page.Icon = (_icon == null ? string.Empty : _icon);
|
page.Icon = (_icon == null ? string.Empty : _icon);
|
||||||
page.Permissions = _permissionGrid.GetPermissions();
|
page.PermissionList = _permissionGrid.GetPermissionList();
|
||||||
page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
|
page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
|
||||||
page.UserId = null;
|
page.UserId = null;
|
||||||
page.Meta = _meta;
|
page.Meta = _meta;
|
||||||
|
@ -158,7 +158,7 @@
|
|||||||
{
|
{
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" />
|
<PermissionGrid EntityName="@EntityNames.Page" PermissionList="@_permissions" @ref="_permissionGrid" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -174,8 +174,8 @@
|
|||||||
<th>@Localizer["ModuleDefinition"]</th>
|
<th>@Localizer["ModuleDefinition"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Settings" Text="Edit" ModuleId="@context.ModuleId" Security="SecurityAccessLevel.Edit" Permissions="@context.Permissions" ResourceKey="ModuleSettings" /></td>
|
<td><ActionLink Action="Settings" Text="Edit" ModuleId="@context.ModuleId" Security="SecurityAccessLevel.Edit" PermissionList="@context.PermissionList" ResourceKey="ModuleSettings" /></td>
|
||||||
<td><ActionDialog Header="Delete Module" Message="Are You Sure You Wish To Delete This Module?" Action="Delete" Security="SecurityAccessLevel.Edit" Permissions="@context.Permissions" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" /></td>
|
<td><ActionDialog Header="Delete Module" Message="Are You Sure You Wish To Delete This Module?" Action="Delete" Security="SecurityAccessLevel.Edit" PermissionList="@context.PermissionList" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" /></td>
|
||||||
<td>@context.Title</td>
|
<td>@context.Title</td>
|
||||||
<td>@context.ModuleDefinition?.Name</td>
|
<td>@context.ModuleDefinition?.Name</td>
|
||||||
</Row>
|
</Row>
|
||||||
@ -221,7 +221,7 @@
|
|||||||
private string _themetype;
|
private string _themetype;
|
||||||
private string _containertype = "-";
|
private string _containertype = "-";
|
||||||
private string _icon;
|
private string _icon;
|
||||||
private string _permissions = null;
|
private List<Permission> _permissions = null;
|
||||||
private string _createdby;
|
private string _createdby;
|
||||||
private DateTime _createdon;
|
private DateTime _createdon;
|
||||||
private string _modifiedby;
|
private string _modifiedby;
|
||||||
@ -292,7 +292,7 @@
|
|||||||
_containertype = PageState.Site.DefaultContainerType;
|
_containertype = PageState.Site.DefaultContainerType;
|
||||||
}
|
}
|
||||||
_icon = page.Icon;
|
_icon = page.Icon;
|
||||||
_permissions = page.Permissions;
|
_permissions = page.PermissionList;
|
||||||
_createdby = page.CreatedBy;
|
_createdby = page.CreatedBy;
|
||||||
_createdon = page.CreatedOn;
|
_createdon = page.CreatedOn;
|
||||||
_modifiedby = page.ModifiedBy;
|
_modifiedby = page.ModifiedBy;
|
||||||
@ -339,7 +339,7 @@
|
|||||||
{
|
{
|
||||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == null))
|
foreach (Page p in PageState.Pages.Where(item => item.ParentId == null))
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
{
|
{
|
||||||
_children.Add(p);
|
_children.Add(p);
|
||||||
}
|
}
|
||||||
@ -349,7 +349,7 @@
|
|||||||
{
|
{
|
||||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid)))
|
foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid)))
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
{
|
{
|
||||||
_children.Add(p);
|
_children.Add(p);
|
||||||
}
|
}
|
||||||
@ -509,7 +509,7 @@
|
|||||||
page.DefaultContainerType = string.Empty;
|
page.DefaultContainerType = string.Empty;
|
||||||
}
|
}
|
||||||
page.Icon = _icon ?? string.Empty;
|
page.Icon = _icon ?? string.Empty;
|
||||||
page.Permissions = _permissionGrid.GetPermissions();
|
page.PermissionList = _permissionGrid.GetPermissionList();
|
||||||
page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
|
page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
|
||||||
page.UserId = null;
|
page.UserId = null;
|
||||||
page.Meta = _meta;
|
page.Meta = _meta;
|
||||||
|
@ -22,7 +22,7 @@ else
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<Pager Items="@_pages.Where(item => item.IsDeleted)">
|
<Pager Items="@_pages.Where(item => item.IsDeleted)" CurrentPage="@_pagePage.ToString()" OnPageChange="OnPageChangePage">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
@ -50,7 +50,7 @@ else
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<Pager Items="@_modules.Where(item => item.IsDeleted)">
|
<Pager Items="@_modules.Where(item => item.IsDeleted)" CurrentPage="@_pageModule.ToString()" OnPageChange="OnPageChangeModule">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
@ -78,7 +78,8 @@ else
|
|||||||
@code {
|
@code {
|
||||||
private List<Page> _pages;
|
private List<Page> _pages;
|
||||||
private List<Module> _modules;
|
private List<Module> _modules;
|
||||||
|
private int _pagePage = 1;
|
||||||
|
private int _pageModule = 1;
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
@ -185,7 +186,7 @@ else
|
|||||||
await PageModuleService.DeletePageModuleAsync(module.PageModuleId);
|
await PageModuleService.DeletePageModuleAsync(module.PageModuleId);
|
||||||
|
|
||||||
// check if there are any remaining module instances in the site
|
// check if there are any remaining module instances in the site
|
||||||
if (!_modules.Exists(item => item.ModuleId == module.ModuleId))
|
if (!_modules.Exists (item => item.ModuleId == module.ModuleId && item.PageModuleId != module.PageModuleId))
|
||||||
{
|
{
|
||||||
await ModuleService.DeleteModuleAsync(module.ModuleId);
|
await ModuleService.DeleteModuleAsync(module.ModuleId);
|
||||||
}
|
}
|
||||||
@ -206,12 +207,14 @@ else
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
ModuleInstance.ShowProgressIndicator();
|
ModuleInstance.ShowProgressIndicator();
|
||||||
foreach (Module module in _modules.Where(item => item.IsDeleted))
|
foreach (Module module in _modules.Where(item => item.IsDeleted).ToList())
|
||||||
{
|
{
|
||||||
await PageModuleService.DeletePageModuleAsync(module.PageModuleId);
|
await PageModuleService.DeletePageModuleAsync(module.PageModuleId);
|
||||||
|
|
||||||
|
// DeletePageModuleAsync does not update _modules so remove it.
|
||||||
|
_modules.Remove(module);
|
||||||
// check if there are any remaining module instances in the site
|
// check if there are any remaining module instances in the site
|
||||||
if (!_modules.Exists(item => item.ModuleId == module.ModuleId))
|
if (!_modules.Exists(item => item.ModuleId == module.ModuleId && item.PageModuleId != module.PageModuleId))
|
||||||
{
|
{
|
||||||
await ModuleService.DeleteModuleAsync(module.ModuleId);
|
await ModuleService.DeleteModuleAsync(module.ModuleId);
|
||||||
}
|
}
|
||||||
@ -229,4 +232,12 @@ else
|
|||||||
ModuleInstance.HideProgressIndicator();
|
ModuleInstance.HideProgressIndicator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void OnPageChangePage(int page)
|
||||||
|
{
|
||||||
|
_pagePage = page;
|
||||||
|
}
|
||||||
|
private void OnPageChangeModule(int page)
|
||||||
|
{
|
||||||
|
_pageModule = page;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@inject IStringLocalizer<Index> Localizer
|
@inject IStringLocalizer<Index> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
@inject ISettingService SettingService
|
||||||
|
|
||||||
@if (PageState.Site.AllowRegistration)
|
@if (PageState.Site.AllowRegistration)
|
||||||
{
|
{
|
||||||
@ -15,7 +16,7 @@
|
|||||||
<ModuleMessage Message="@Localizer["Info.Registration.Exists"]" Type="MessageType.Info" />
|
<ModuleMessage Message="@Localizer["Info.Registration.Exists"]" Type="MessageType.Info" />
|
||||||
</Authorized>
|
</Authorized>
|
||||||
<NotAuthorized>
|
<NotAuthorized>
|
||||||
<ModuleMessage Message="@Localizer["Info.Registration.InvalidEmail"]" Type="MessageType.Info" />
|
<ModuleMessage Message="@_passwordconstruction" Type="MessageType.Info" />
|
||||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -29,7 +30,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -38,7 +39,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@_confirm" autocomplete="new-password" required />
|
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@_confirm" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -78,11 +79,44 @@ else
|
|||||||
private string _email = string.Empty;
|
private string _email = string.Empty;
|
||||||
private string _displayname = string.Empty;
|
private string _displayname = string.Empty;
|
||||||
|
|
||||||
|
//Password construction
|
||||||
|
private string _minimumlength;
|
||||||
|
private string _uniquecharacters;
|
||||||
|
private bool _requiredigit;
|
||||||
|
private bool _requireupper;
|
||||||
|
private bool _requirelower;
|
||||||
|
private bool _requirepunctuation;
|
||||||
|
private string _passwordconstruction;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||||
|
|
||||||
|
_minimumlength = SettingService.GetSetting(settings, "IdentityOptions:Password:RequiredLength", "6");
|
||||||
|
_uniquecharacters = SettingService.GetSetting(settings, "IdentityOptions:Password:RequiredUniqueChars", "1");
|
||||||
|
_requiredigit = bool.Parse(SettingService.GetSetting(settings, "IdentityOptions:Password:RequireDigit", "true"));
|
||||||
|
_requireupper = bool.Parse(SettingService.GetSetting(settings, "IdentityOptions:Password:RequireUppercase", "true"));
|
||||||
|
_requirelower = bool.Parse(SettingService.GetSetting(settings, "IdentityOptions:Password:RequireLowercase", "true"));
|
||||||
|
_requirepunctuation = bool.Parse(SettingService.GetSetting(settings, "IdentityOptions:Password:RequireNonAlphanumeric", "true"));
|
||||||
|
|
||||||
|
// Replace the placeholders with the actual values of the variables
|
||||||
|
string digitRequirement = _requiredigit ? Localizer["Password.DigitRequirement"] + ", " : "";
|
||||||
|
string uppercaseRequirement = _requireupper ? Localizer["Password.UppercaseRequirement"] + ", " : "";
|
||||||
|
string lowercaseRequirement = _requirelower ? Localizer["Password.LowercaseRequirement"] + ", " : "";
|
||||||
|
string punctuationRequirement = _requirepunctuation ? Localizer["Password.PunctuationRequirement"] + ", " : "";
|
||||||
|
|
||||||
|
// Replace the placeholders with the actual values of the variables
|
||||||
|
string passwordValidationCriteriaTemplate = Localizer["Password.ValidationCriteria"];
|
||||||
|
_passwordconstruction = Localizer["Info.Registration.InvalidEmail"] + ". " + string.Format(passwordValidationCriteriaTemplate,
|
||||||
|
_minimumlength, _uniquecharacters, digitRequirement, uppercaseRequirement, lowercaseRequirement, punctuationRequirement);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Register()
|
private async Task Register()
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@_confirm" autocomplete="new-password" required />
|
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@_confirm" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
<option value="-"><@Localizer["Not Specified"]></option>
|
<option value="-"><@Localizer["Not Specified"]></option>
|
||||||
@foreach (Page page in PageState.Pages)
|
@foreach (Page page in PageState.Pages)
|
||||||
{
|
{
|
||||||
if (UserSecurity.ContainsRole(page.Permissions, PermissionNames.View, RoleNames.Everyone))
|
if (UserSecurity.ContainsRole(page.PermissionList, PermissionNames.View, RoleNames.Everyone))
|
||||||
{
|
{
|
||||||
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
|
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
|
||||||
}
|
}
|
||||||
@ -95,6 +95,12 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="sitemap" HelpText="The site map url for this site which can be submitted to search engines for indexing" ResourceKey="SiteMap">Site Map: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="sitemap" class="form-control" @bind="@_sitemap" required disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
|
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -137,7 +143,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_smtppasswordtype" class="form-control" @bind="@_smtppassword" />
|
<input id="password" type="@_smtppasswordtype" class="form-control" @bind="@_smtppassword" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@ToggleSMTPPassword">@_togglesmtppassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@ToggleSMTPPassword" tabindex="-1">@_togglesmtppassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -267,16 +273,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Section>
|
</Section>
|
||||||
<Section Name="TenantInformation" Heading="Tenant Information" ResourceKey="TenantInformation">
|
<Section Name="TenantInformation" Heading="Database" ResourceKey="TenantInformation">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="tenant" HelpText="The tenant for the site" ResourceKey="Tenant">Tenant: </Label>
|
<Label Class="col-sm-3" For="tenant" HelpText="The name of the database used for the site" ResourceKey="Tenant">Database: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="tenant" class="form-control" @bind="@_tenant" readonly />
|
<input id="tenant" class="form-control" @bind="@_tenant" readonly />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="database" HelpText="The database for the tenant" ResourceKey="Database">Database: </Label>
|
<Label Class="col-sm-3" For="database" HelpText="The type of database" ResourceKey="Database">Type: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="database" class="form-control" @bind="@_database" readonly />
|
<input id="database" class="form-control" @bind="@_database" readonly />
|
||||||
</div>
|
</div>
|
||||||
@ -284,7 +290,7 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="connectionstring" HelpText="The connection information for the database" ResourceKey="ConnectionString">Connection: </Label>
|
<Label Class="col-sm-3" For="connectionstring" HelpText="The connection information for the database" ResourceKey="ConnectionString">Connection: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<textarea id="connectionstring" class="form-control" @bind="@_connectionstring" rows="2" readonly></textarea>
|
<input id="connectionstring" class="form-control" @bind="@_connectionstring" readonly />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -321,6 +327,7 @@
|
|||||||
private string _containertype = "-";
|
private string _containertype = "-";
|
||||||
private string _admincontainertype = "-";
|
private string _admincontainertype = "-";
|
||||||
private string _homepageid = "-";
|
private string _homepageid = "-";
|
||||||
|
private string _sitemap = "";
|
||||||
private string _smtphost = string.Empty;
|
private string _smtphost = string.Empty;
|
||||||
private string _smtpport = string.Empty;
|
private string _smtpport = string.Empty;
|
||||||
private string _smtpssl = "False";
|
private string _smtpssl = "False";
|
||||||
@ -361,6 +368,7 @@
|
|||||||
_runtime = site.Runtime;
|
_runtime = site.Runtime;
|
||||||
_prerender = site.RenderMode.Replace(_runtime, "");
|
_prerender = site.RenderMode.Replace(_runtime, "");
|
||||||
_isdeleted = site.IsDeleted.ToString();
|
_isdeleted = site.IsDeleted.ToString();
|
||||||
|
_sitemap = PageState.Alias.Protocol + PageState.Alias.Name + "/pages/sitemap.xml";
|
||||||
|
|
||||||
await GetAliases();
|
await GetAliases();
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ else
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="tenant" HelpText="Select the tenant for the site" ResourceKey="Tenant">Tenant: </Label>
|
<Label Class="col-sm-3" For="tenant" HelpText="Select the database for the site" ResourceKey="Tenant">Database: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="tenant" class="form-select" @onchange="(e => TenantChanged(e))" required>
|
<select id="tenant" class="form-select" @onchange="(e => TenantChanged(e))" required>
|
||||||
<option value="-"><@Localizer["Tenant.Select"]></option>
|
<option value="-"><@Localizer["Tenant.Select"]></option>
|
||||||
@ -121,13 +121,13 @@ else
|
|||||||
<hr class="app-rule" />
|
<hr class="app-rule" />
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="name" HelpText="Enter the name for the tenant" ResourceKey="TenantName">Tenant Name: </Label>
|
<Label Class="col-sm-3" For="name" HelpText="Enter the name for the database" ResourceKey="TenantName">Name: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="name" class="form-control" @bind="@_tenantName" maxlength="100" required />
|
<input id="name" class="form-control" @bind="@_tenantName" maxlength="100" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="databaseType" HelpText="Select the database type for the tenant" ResourceKey="DatabaseType">Database Type: </Label>
|
<Label Class="col-sm-3" For="databaseType" HelpText="Select the database type" ResourceKey="DatabaseType">Type: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@if (_databases != null)
|
@if (_databases != null)
|
||||||
{
|
{
|
||||||
@ -160,7 +160,7 @@ else
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="connectionstring" HelpText="Enter a complete connection string including all parameters and delimiters" ResourceKey="ConnectionString">String:</Label>
|
<Label Class="col-sm-3" For="connectionstring" HelpText="Enter a complete connection string including all parameters and delimiters" ResourceKey="ConnectionString">Settings:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<textarea id="connectionstring" class="form-control" @bind="@_connectionString" rows="3"></textarea>
|
<textarea id="connectionstring" class="form-control" @bind="@_connectionString" rows="3"></textarea>
|
||||||
</div>
|
</div>
|
||||||
@ -315,7 +315,7 @@ else
|
|||||||
_urls = Regex.Replace(_urls, @"\r\n?|\n", ",");
|
_urls = Regex.Replace(_urls, @"\r\n?|\n", ",");
|
||||||
var duplicates = new List<string>();
|
var duplicates = new List<string>();
|
||||||
var aliases = await AliasService.GetAliasesAsync();
|
var aliases = await AliasService.GetAliasesAsync();
|
||||||
foreach (string name in _urls.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
foreach (string name in _urls.Split(',', StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
if (aliases.Exists(item => item.Name == name))
|
if (aliases.Exists(item => item.Name == name))
|
||||||
{
|
{
|
||||||
@ -329,7 +329,7 @@ else
|
|||||||
|
|
||||||
if (_tenantid == "+")
|
if (_tenantid == "+")
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_tenantName) && _tenants.FirstOrDefault(item => item.Name == _tenantName) == null)
|
if (!string.IsNullOrEmpty(_tenantName) && !_tenants.Exists(item => item.Name == _tenantName))
|
||||||
{
|
{
|
||||||
// validate host credentials
|
// validate host credentials
|
||||||
var user = new User();
|
var user = new User();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
@namespace Oqtane.Modules.Admin.Sql
|
@namespace Oqtane.Modules.Admin.Sql
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject ISystemService SystemService
|
||||||
@inject ITenantService TenantService
|
@inject ITenantService TenantService
|
||||||
@inject IDatabaseService DatabaseService
|
@inject IDatabaseService DatabaseService
|
||||||
@inject ISqlService SqlService
|
@inject ISqlService SqlService
|
||||||
@ -14,29 +15,100 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="tenant" HelpText="Select the tenant associated with the database server" ResourceKey="Tenant">Tenant: </Label>
|
<Label Class="col-sm-3" For="connection" HelpText="Select a database connection (from appsettings.json)" ResourceKey="Connection">Connection: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="tenant" class="form-select" value="@_tenantid" @onchange="(e => TenantChanged(e))">
|
<select id="tenant" class="form-select" value="@_connection" @onchange="(e => ConnectionChanged(e))">
|
||||||
<option value="-1"><@Localizer["Tenant.Select"]></option>
|
<option value="-"><@Localizer["Connection.Select"]></option>
|
||||||
@foreach (Tenant tenant in _tenants)
|
<option value="+"><@Localizer["Connection.Add"]></option>
|
||||||
|
@foreach (var connection in _connections)
|
||||||
{
|
{
|
||||||
<option value="@tenant.TenantId">@tenant.Name</option>
|
<option value="@connection.Key">@connection.Key</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if (_tenantid != "-1")
|
@if (_connection == "+")
|
||||||
{
|
{
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="database" HelpText="The database for the tenant" ResourceKey="Database">Database: </Label>
|
<Label Class="col-sm-3" For="name" HelpText="Enter the name of the connection" ResourceKey="Name">Name: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="database" class="form-control" @bind="@_database" readonly />
|
<input id="name" class="form-control" @bind="@_name" maxlength="100" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="connectionstring" HelpText="The connection information for the database" ResourceKey="ConnectionString">Connection: </Label>
|
<Label Class="col-sm-3" For="databasetype" HelpText="Select the database type" ResourceKey="DatabaseType">Type: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
@if (_databases != null)
|
||||||
|
{
|
||||||
|
<div class="input-group">
|
||||||
|
<select id="databasetype" class="form-select" value="@_databasetype" @onchange="(e => DatabaseTypeChanged(e))" required>
|
||||||
|
@foreach (var database in _databases)
|
||||||
|
{
|
||||||
|
<option value="@database.Name">@Localizer[@database.Name]</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
@if (!_showConnectionString)
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="ShowConnectionString">@Localizer["EnterConnectionString"]</button>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="ShowConnectionString">@Localizer["EnterConnectionParameters"]</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (!_showConnectionString)
|
||||||
|
{
|
||||||
|
if (_databaseConfigType != null)
|
||||||
|
{
|
||||||
|
@DatabaseConfigComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="connectionstring" HelpText="Enter a complete connection string including all parameters and delimiters" ResourceKey="ConnectionString">Settings:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="connectionstring" class="form-control" @bind="@_connectionstring" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<br />
|
||||||
|
<button type="button" class="btn btn-success" @onclick="Add">@Localizer["Add"]</button>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@if (_connection != "-")
|
||||||
|
{
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="databasetype" HelpText="The database type" ResourceKey="DatabaseType">Type: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
@if (_databases != null)
|
||||||
|
{
|
||||||
|
<select id="databasetype" class="form-select" @bind="@_databasetype" required>
|
||||||
|
<option value="-"><@Localizer["Type.Select"]></option>
|
||||||
|
@foreach (var database in _databases)
|
||||||
|
{
|
||||||
|
<option value="@database.Name">@Localizer[@database.Name]</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (!string.IsNullOrEmpty(_tenant))
|
||||||
|
{
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="tenant" HelpText="The database using this connection" ResourceKey="Tenant">Database: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="tenant" class="form-control" @bind="@_tenant" readonly />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="connectionstring" HelpText="The connection string" ResourceKey="ConnectionString">Settings: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="connectionstring" type="@_connectionstringtype" class="form-control" @bind="@_connectionstring" readonly />
|
<input id="connectionstring" type="@_connectionstringtype" class="form-control" @bind="@_connectionstring" readonly />
|
||||||
@ -45,13 +117,11 @@ else
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="sqlQuery" HelpText="Enter the SQL query for the database server" ResourceKey="SqlQuery">SQL Query: </Label>
|
<Label Class="col-sm-3" For="sqlQuery" HelpText="Enter a valid SQL query for the database" ResourceKey="SqlQuery">SQL Query: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<textarea id="sqlQuery" class="form-control" @bind="@_sql" rows="3"></textarea>
|
<textarea id="sqlQuery" class="form-control" @bind="@_sql" rows="3"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<br />
|
<br />
|
||||||
<button type="button" class="btn btn-success" @onclick="Execute">@Localizer["Execute"]</button>
|
<button type="button" class="btn btn-success" @onclick="Execute">@Localizer["Execute"]</button>
|
||||||
<br />
|
<br />
|
||||||
@ -80,14 +150,27 @@ else
|
|||||||
@Localizer["Return.NoResult"]
|
@Localizer["Return.NoResult"]
|
||||||
}
|
}
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private string _connection = "-";
|
||||||
|
private Dictionary<string, object> _connections;
|
||||||
private List<Tenant> _tenants;
|
private List<Tenant> _tenants;
|
||||||
private string _tenantid = "-1";
|
private List<Database> _databases;
|
||||||
private string _database = string.Empty;
|
|
||||||
|
private string _name = string.Empty;
|
||||||
|
private string _databasetype = string.Empty;
|
||||||
|
private Type _databaseConfigType;
|
||||||
|
private object _databaseConfig;
|
||||||
|
private RenderFragment DatabaseConfigComponent { get; set; }
|
||||||
|
private bool _showConnectionString = false;
|
||||||
|
private string _tenant = string.Empty;
|
||||||
private string _connectionstring = string.Empty;
|
private string _connectionstring = string.Empty;
|
||||||
private string _connectionstringtype = "password";
|
private string _connectionstringtype = "password";
|
||||||
private string _connectionstringtoggle = string.Empty;
|
private string _connectionstringtoggle = string.Empty;
|
||||||
@ -100,7 +183,9 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_connections = await SystemService.GetSystemInfoAsync("connectionstrings");
|
||||||
_tenants = await TenantService.GetTenantsAsync();
|
_tenants = await TenantService.GetTenantsAsync();
|
||||||
|
_databases = await DatabaseService.GetDatabasesAsync();
|
||||||
_connectionstringtoggle = SharedLocalizer["ShowPassword"];
|
_connectionstringtoggle = SharedLocalizer["ShowPassword"];
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -110,28 +195,105 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void TenantChanged(ChangeEventArgs e)
|
private async void ConnectionChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_tenantid = (string)e.Value;
|
_connection = (string)e.Value;
|
||||||
var tenants = await TenantService.GetTenantsAsync();
|
if (_connection != "-" && _connection != "+")
|
||||||
var _databases = await DatabaseService.GetDatabasesAsync();
|
{
|
||||||
var tenant = tenants.Find(item => item.TenantId == int.Parse(_tenantid));
|
_connectionstring = _connections[_connection].ToString();
|
||||||
|
_tenant = "";
|
||||||
|
_databasetype = "-";
|
||||||
|
var tenant = _tenants.FirstOrDefault(item => item.DBConnectionString == _connection);
|
||||||
if (tenant != null)
|
if (tenant != null)
|
||||||
{
|
{
|
||||||
_database = _databases.Find(item => item.DBType == tenant.DBType)?.Name;
|
_tenant = tenant.Name;
|
||||||
_connectionstring = tenant.DBConnectionString;
|
_databasetype = _databases.FirstOrDefault(item => item.DBType == tenant.DBType).Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_databases.Exists(item => item.IsDefault))
|
||||||
|
{
|
||||||
|
_databasetype = _databases.Find(item => item.IsDefault).Name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_databasetype = "LocalDB";
|
||||||
|
}
|
||||||
|
_showConnectionString = false;
|
||||||
|
LoadDatabaseConfigComponent();
|
||||||
}
|
}
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Loading Tenant {TenantId} {Error}", _tenantid, ex.Message);
|
await logger.LogError(ex, "Error Loading Connection {Connection} {Error}", _connection, ex.Message);
|
||||||
AddModuleMessage(ex.Message, MessageType.Error);
|
AddModuleMessage(ex.Message, MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DatabaseTypeChanged(ChangeEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_databasetype = (string)eventArgs.Value;
|
||||||
|
_showConnectionString = false;
|
||||||
|
LoadDatabaseConfigComponent();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Error.Database.LoadConfig"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadDatabaseConfigComponent()
|
||||||
|
{
|
||||||
|
var database = _databases.SingleOrDefault(d => d.Name == _databasetype);
|
||||||
|
if (database != null)
|
||||||
|
{
|
||||||
|
_databaseConfigType = Type.GetType(database.ControlType);
|
||||||
|
DatabaseConfigComponent = builder =>
|
||||||
|
{
|
||||||
|
builder.OpenComponent(0, _databaseConfigType);
|
||||||
|
builder.AddComponentReferenceCapture(1, inst => { _databaseConfig = Convert.ChangeType(inst, _databaseConfigType); });
|
||||||
|
builder.CloseComponent();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowConnectionString()
|
||||||
|
{
|
||||||
|
if (_databaseConfig is IDatabaseConfigControl databaseConfigControl)
|
||||||
|
{
|
||||||
|
_connectionstring = databaseConfigControl.GetConnectionString();
|
||||||
|
}
|
||||||
|
_showConnectionString = !_showConnectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Add()
|
||||||
|
{
|
||||||
|
var connectionstring = _connectionstring;
|
||||||
|
if (!_showConnectionString && _databaseConfig is IDatabaseConfigControl databaseConfigControl)
|
||||||
|
{
|
||||||
|
connectionstring = databaseConfigControl.GetConnectionString();
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(_name) && !string.IsNullOrEmpty(connectionstring))
|
||||||
|
{
|
||||||
|
var settings = new Dictionary<string, object>();
|
||||||
|
settings.Add($"{SettingKeys.ConnectionStringsSection}:{_name}", connectionstring);
|
||||||
|
await SystemService.UpdateSystemInfoAsync(settings);
|
||||||
|
_connections = await SystemService.GetSystemInfoAsync("connectionstrings");
|
||||||
|
_connection = "-";
|
||||||
|
AddModuleMessage(Localizer["Message.Connection.Added"], MessageType.Success);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.Required.Connection"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ToggleConnectionString()
|
private void ToggleConnectionString()
|
||||||
{
|
{
|
||||||
if (_connectionstringtype == "password")
|
if (_connectionstringtype == "password")
|
||||||
@ -150,9 +312,10 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_tenantid != "-1" && !string.IsNullOrEmpty(_sql))
|
if (_databasetype != "-" && !string.IsNullOrEmpty(_sql))
|
||||||
{
|
{
|
||||||
var sqlquery = new SqlQuery { TenantId = int.Parse(_tenantid), Query = _sql };
|
var dbtype = _databases.FirstOrDefault(item => item.Name == _databasetype).DBType;
|
||||||
|
var sqlquery = new SqlQuery { DBConnectionString = _connection, DBType = dbtype, Query = _sql };
|
||||||
sqlquery = await SqlService.ExecuteQueryAsync(sqlquery);
|
sqlquery = await SqlService.ExecuteQueryAsync(sqlquery);
|
||||||
_results = sqlquery.Results;
|
_results = sqlquery.Results;
|
||||||
AddModuleMessage(Localizer["Success.QueryExecuted"], MessageType.Success);
|
AddModuleMessage(Localizer["Success.QueryExecuted"], MessageType.Success);
|
||||||
|
@ -156,6 +156,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<br /><br />
|
||||||
|
<button type="button" class="btn btn-danger" @onclick="ClearLog">@Localizer["Clear"]</button>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabStrip>
|
</TabStrip>
|
||||||
<br /><br />
|
<br /><br />
|
||||||
@ -188,7 +190,7 @@
|
|||||||
{
|
{
|
||||||
_version = Constants.Version;
|
_version = Constants.Version;
|
||||||
|
|
||||||
Dictionary<string, object> systeminfo = await SystemService.GetSystemInfoAsync("environment");
|
var systeminfo = await SystemService.GetSystemInfoAsync("environment");
|
||||||
if (systeminfo != null)
|
if (systeminfo != null)
|
||||||
{
|
{
|
||||||
_clrversion = systeminfo["CLRVersion"].ToString();
|
_clrversion = systeminfo["CLRVersion"].ToString();
|
||||||
@ -241,6 +243,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task ClearLog()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var settings = new Dictionary<string, object>();
|
||||||
|
settings.Add("clearlog", "true");
|
||||||
|
await SystemService.UpdateSystemInfoAsync(settings);
|
||||||
|
_log = string.Empty;
|
||||||
|
AddModuleMessage(Localizer["Success.ClearLog"], MessageType.Success);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Clearing Log");
|
||||||
|
AddModuleMessage(Localizer["Error.ClearLog"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task RestartApplication()
|
private async Task RestartApplication()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -65,13 +65,15 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
<br />
|
||||||
|
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Upload" ResourceKey="Upload">
|
<TabPanel Name="Upload" ResourceKey="Upload">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" HelpText="Upload one or more theme packages. Once they are uploaded click Install to complete the installation." ResourceKey="Theme">Theme: </Label>
|
<Label Class="col-sm-3" HelpText="Upload one or more theme packages. Once they are uploaded click Install to complete the installation." ResourceKey="Theme">Theme: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" />
|
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" OnUpload="OnUpload" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -111,13 +113,8 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button type="button" class="btn btn-success" @onclick="InstallThemes">@SharedLocalizer["Install"]</button>
|
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private string _price = "free";
|
private string _price = "free";
|
||||||
@ -236,7 +233,7 @@
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_packageid, _version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_packageid, _version, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _version);
|
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _version);
|
||||||
AddModuleMessage(Localizer["Success.Theme.Download"], MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Theme.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_productname = "";
|
_productname = "";
|
||||||
_license = "";
|
_license = "";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
@ -248,16 +245,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InstallThemes()
|
private void OnUpload()
|
||||||
{
|
{
|
||||||
try
|
AddModuleMessage(string.Format(Localizer["Success.Theme.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
{
|
|
||||||
await ThemeService.InstallThemesAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Installing Theme");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@
|
|||||||
private bool IsValid(string name)
|
private bool IsValid(string name)
|
||||||
{
|
{
|
||||||
// must contain letters, underscores and digits and first character must be letter or underscore
|
// must contain letters, underscores and digits and first character must be letter or underscore
|
||||||
return !string.IsNullOrEmpty(name) && name.ToLower() != "theme" && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
|
return !string.IsNullOrEmpty(name) && name.ToLower() != "theme" && !name.ToLower().Contains("oqtane") && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TemplateChanged(ChangeEventArgs e)
|
private void TemplateChanged(ChangeEventArgs e)
|
||||||
|
@ -116,7 +116,6 @@ else
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version);
|
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version);
|
||||||
await ThemeService.InstallThemesAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -34,7 +34,7 @@ else
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
|
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -43,7 +43,7 @@ else
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
|
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -211,8 +211,11 @@ else
|
|||||||
</Detail>
|
</Detail>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
|
@if (notifications.Any())
|
||||||
|
{
|
||||||
<br />
|
<br />
|
||||||
<ActionDialog Header="Clear Notifications" Message="Are You Sure You Wish To Permanently Delete All Notifications ?" Action="Delete All Notifications" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllNotifications())" ResourceKey="DeleteAllNotifications" />
|
<ActionDialog Header="Clear Notifications" Message="Are You Sure You Wish To Permanently Delete All Notifications ?" Action="Delete All Notifications" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllNotifications())" ResourceKey="DeleteAllNotifications" />
|
||||||
|
}
|
||||||
<br /><hr />
|
<br /><hr />
|
||||||
<select class="form-select" @onchange="(e => FilterChanged(e))">
|
<select class="form-select" @onchange="(e => FilterChanged(e))">
|
||||||
<option value="to">@Localizer["Inbox"]</option>
|
<option value="to">@Localizer["Inbox"]</option>
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -32,7 +32,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" required />
|
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,7 +32,7 @@ else
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
|
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -41,7 +41,7 @@ else
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
|
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -294,6 +294,12 @@ else
|
|||||||
<input id="roleclaimtype" class="form-control" @bind="@_roleclaimtype" />
|
<input id="roleclaimtype" class="form-control" @bind="@_roleclaimtype" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="profileclaimtypes" HelpText="A comma delimited list of user profile claims provided by the provider, as well as mappings to your user profile definition. For example if the provider includes a 'given_name' claim and you have a 'FirstName' user profile definition you should specify 'given_name:FirstName'." ResourceKey="ProfileClaimTypes">User Profile Claims:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="profileclaimtypes" class="form-control" @bind="@_profileclaimtypes" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="domainfilter" HelpText="Provide any email domain filter criteria (separated by commas). Domains to exclude should be prefixed with an exclamation point (!). For example 'microsoft.com,!hotmail.com' would include microsoft.com email addresses but not hotmail.com email addresses." ResourceKey="DomainFilter">Domain Filter:</Label>
|
<Label Class="col-sm-3" For="domainfilter" HelpText="Provide any email domain filter criteria (separated by commas). Domains to exclude should be prefixed with an exclamation point (!). For example 'microsoft.com,!hotmail.com' would include microsoft.com email addresses but not hotmail.com email addresses." ResourceKey="DomainFilter">Domain Filter:</Label>
|
||||||
@ -395,6 +401,7 @@ else
|
|||||||
private string _identifierclaimtype;
|
private string _identifierclaimtype;
|
||||||
private string _emailclaimtype;
|
private string _emailclaimtype;
|
||||||
private string _roleclaimtype;
|
private string _roleclaimtype;
|
||||||
|
private string _profileclaimtypes;
|
||||||
private string _domainfilter;
|
private string _domainfilter;
|
||||||
private string _createusers;
|
private string _createusers;
|
||||||
|
|
||||||
@ -449,6 +456,7 @@ else
|
|||||||
_identifierclaimtype = SettingService.GetSetting(settings, "ExternalLogin:IdentifierClaimType", "sub");
|
_identifierclaimtype = SettingService.GetSetting(settings, "ExternalLogin:IdentifierClaimType", "sub");
|
||||||
_emailclaimtype = SettingService.GetSetting(settings, "ExternalLogin:EmailClaimType", "email");
|
_emailclaimtype = SettingService.GetSetting(settings, "ExternalLogin:EmailClaimType", "email");
|
||||||
_roleclaimtype = SettingService.GetSetting(settings, "ExternalLogin:RoleClaimType", "");
|
_roleclaimtype = SettingService.GetSetting(settings, "ExternalLogin:RoleClaimType", "");
|
||||||
|
_profileclaimtypes = SettingService.GetSetting(settings, "ExternalLogin:ProfileClaimTypes", "");
|
||||||
_domainfilter = SettingService.GetSetting(settings, "ExternalLogin:DomainFilter", "");
|
_domainfilter = SettingService.GetSetting(settings, "ExternalLogin:DomainFilter", "");
|
||||||
_createusers = SettingService.GetSetting(settings, "ExternalLogin:CreateUsers", "true");
|
_createusers = SettingService.GetSetting(settings, "ExternalLogin:CreateUsers", "true");
|
||||||
|
|
||||||
@ -568,6 +576,7 @@ else
|
|||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:IdentifierClaimType", _identifierclaimtype, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:IdentifierClaimType", _identifierclaimtype, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:EmailClaimType", _emailclaimtype, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:EmailClaimType", _emailclaimtype, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:RoleClaimType", _roleclaimtype, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:RoleClaimType", _roleclaimtype, true);
|
||||||
|
settings = SettingService.SetSetting(settings, "ExternalLogin:ProfileClaimTypes", _profileclaimtypes, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:DomainFilter", _domainfilter, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:DomainFilter", _domainfilter, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:CreateUsers", _createusers, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:CreateUsers", _createusers, true);
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
|
@using System.Text.Json
|
||||||
@inherits LocalizableComponent
|
@inherits LocalizableComponent
|
||||||
|
|
||||||
@if (_visible)
|
@if (_visible)
|
||||||
@ -40,7 +41,7 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
private bool _visible = false;
|
private bool _visible = false;
|
||||||
private string _permissions = string.Empty;
|
private List<Permission> _permissions;
|
||||||
private bool _editmode = false;
|
private bool _editmode = false;
|
||||||
private bool _authorized = false;
|
private bool _authorized = false;
|
||||||
private string _iconSpan = string.Empty;
|
private string _iconSpan = string.Empty;
|
||||||
@ -61,7 +62,10 @@
|
|||||||
public SecurityAccessLevel? Security { get; set; } // optional - can be used to explicitly specify SecurityAccessLevel
|
public SecurityAccessLevel? Security { get; set; } // optional - can be used to explicitly specify SecurityAccessLevel
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Permissions { get; set; } // optional - can be used to specify a permission string
|
public string Permissions { get; set; } // deprecated - use PermissionList instead
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public List<Permission> PermissionList { get; set; } // optional - can be used to specify permissions
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Class { get; set; } // optional
|
public string Class { get; set; } // optional
|
||||||
@ -78,6 +82,14 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string IconName { get; set; } // optional - specifies an icon for the link - default is no icon
|
public string IconName { get; set; } // optional - specifies an icon for the link - default is no icon
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(Permissions))
|
||||||
|
{
|
||||||
|
PermissionList = JsonSerializer.Deserialize<List<Permission>>(Permissions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
base.OnParametersSet();
|
base.OnParametersSet();
|
||||||
@ -109,7 +121,7 @@
|
|||||||
Header = Localize(nameof(Header), Header);
|
Header = Localize(nameof(Header), Header);
|
||||||
Message = Localize(nameof(Message), Message);
|
Message = Localize(nameof(Message), Message);
|
||||||
|
|
||||||
_permissions = (string.IsNullOrEmpty(Permissions)) ? ModuleState.Permissions : Permissions;
|
_permissions = (PermissionList == null) ? ModuleState.PermissionList : PermissionList;
|
||||||
_authorized = IsAuthorized();
|
_authorized = IsAuthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@using System.Net
|
@using System.Net
|
||||||
|
@using System.Text.Json
|
||||||
@inherits LocalizableComponent
|
@inherits LocalizableComponent
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
|
|
||||||
@ -26,7 +27,7 @@
|
|||||||
private string _text = string.Empty;
|
private string _text = string.Empty;
|
||||||
private string _parameters = string.Empty;
|
private string _parameters = string.Empty;
|
||||||
private string _url = string.Empty;
|
private string _url = string.Empty;
|
||||||
private string _permissions = string.Empty;
|
private List<Permission> _permissions;
|
||||||
private bool _editmode = false;
|
private bool _editmode = false;
|
||||||
private bool _authorized = false;
|
private bool _authorized = false;
|
||||||
private string _classname = "btn btn-primary";
|
private string _classname = "btn btn-primary";
|
||||||
@ -52,7 +53,10 @@
|
|||||||
public SecurityAccessLevel? Security { get; set; } // optional - can be used to explicitly specify SecurityAccessLevel
|
public SecurityAccessLevel? Security { get; set; } // optional - can be used to explicitly specify SecurityAccessLevel
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Permissions { get; set; } // optional - can be used to specify a permission string
|
public string Permissions { get; set; } // deprecated - use PermissionList instead
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public List<Permission> PermissionList { get; set; } // optional - can be used to specify permissions
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public bool Disabled { get; set; } // optional
|
public bool Disabled { get; set; } // optional
|
||||||
@ -75,6 +79,14 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string ReturnUrl { get; set; } // optional - used to set a url to redirect to
|
public string ReturnUrl { get; set; } // optional - used to set a url to redirect to
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(Permissions))
|
||||||
|
{
|
||||||
|
PermissionList = JsonSerializer.Deserialize<List<Permission>>(Permissions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
base.OnParametersSet();
|
base.OnParametersSet();
|
||||||
@ -119,7 +131,7 @@
|
|||||||
_iconSpan = $"<span class=\"{IconName}\"></span>{(IconOnly ? "" : " ")}";
|
_iconSpan = $"<span class=\"{IconName}\"></span>{(IconOnly ? "" : " ")}";
|
||||||
}
|
}
|
||||||
|
|
||||||
_permissions = (string.IsNullOrEmpty(Permissions)) ? ModuleState.Permissions : Permissions;
|
_permissions = (PermissionList == null) ? ModuleState.PermissionList : PermissionList;
|
||||||
_text = Localize(nameof(Text), _text);
|
_text = Localize(nameof(Text), _text);
|
||||||
_url = (ModuleId == -1) ? EditUrl(Action, _parameters) : EditUrl(ModuleId, Action, _parameters);
|
_url = (ModuleId == -1) ? EditUrl(Action, _parameters) : EditUrl(ModuleId, Action, _parameters);
|
||||||
if (!string.IsNullOrEmpty(ReturnUrl))
|
if (!string.IsNullOrEmpty(ReturnUrl))
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
@inject IStringLocalizer<FileManager> Localizer
|
@inject IStringLocalizer<FileManager> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
@if (_folders != null)
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
<div id="@Id" class="container-fluid px-0">
|
<div id="@Id" class="container-fluid px-0">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -87,6 +87,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
private List<Folder> _folders;
|
private List<Folder> _folders;
|
||||||
private List<File> _files = new List<File>();
|
private List<File> _files = new List<File>();
|
||||||
private string _fileinputid = string.Empty;
|
private string _fileinputid = string.Empty;
|
||||||
@ -205,6 +206,8 @@
|
|||||||
_fileinputid = "FileInput_" + _guid;
|
_fileinputid = "FileInput_" + _guid;
|
||||||
_progressinfoid = "ProgressInfo_" + _guid;
|
_progressinfoid = "ProgressInfo_" + _guid;
|
||||||
_progressbarid = "ProgressBar_" + _guid;
|
_progressbarid = "ProgressBar_" + _guid;
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task GetFiles()
|
private async Task GetFiles()
|
||||||
@ -220,7 +223,7 @@
|
|||||||
Folder folder = _folders.FirstOrDefault(item => item.FolderId == FolderId);
|
Folder folder = _folders.FirstOrDefault(item => item.FolderId == FolderId);
|
||||||
if (folder != null)
|
if (folder != null)
|
||||||
{
|
{
|
||||||
_haseditpermission = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, folder.Permissions);
|
_haseditpermission = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, folder.PermissionList);
|
||||||
_files = await FileService.GetFilesAsync(FolderId);
|
_files = await FileService.GetFilesAsync(FolderId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -228,7 +231,6 @@
|
|||||||
_haseditpermission = false;
|
_haseditpermission = false;
|
||||||
_files = new List<File>();
|
_files = new List<File>();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (_filter != "*")
|
if (_filter != "*")
|
||||||
{
|
{
|
||||||
List<File> filtered = new List<File>();
|
List<File> filtered = new List<File>();
|
||||||
@ -242,6 +244,7 @@
|
|||||||
_files = filtered;
|
_files = filtered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task FolderChanged(ChangeEventArgs e)
|
private async Task FolderChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
@ -367,6 +370,12 @@
|
|||||||
_messagetype = MessageType.Error;
|
_messagetype = MessageType.Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Folder == Constants.PackagesFolder)
|
||||||
|
{
|
||||||
|
await OnUpload.InvokeAsync(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// set FileId to first file in upload collection
|
// set FileId to first file in upload collection
|
||||||
await GetFiles();
|
await GetFiles();
|
||||||
var file = _files.Where(item => item.Name == uploads[0]).FirstOrDefault();
|
var file = _files.Where(item => item.Name == uploads[0]).FirstOrDefault();
|
||||||
@ -377,6 +386,7 @@
|
|||||||
await OnUpload.InvokeAsync(FileId);
|
await OnUpload.InvokeAsync(FileId);
|
||||||
}
|
}
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
|
@using System.Text.Json
|
||||||
@inherits ModuleControlBase
|
@inherits ModuleControlBase
|
||||||
@inject IRoleService RoleService
|
@inject IRoleService RoleService
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@ -15,20 +16,19 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">@Localizer["Role"]</th>
|
<th scope="col">@Localizer["Role"]</th>
|
||||||
@foreach (PermissionString permission in _permissions)
|
@foreach (var permissionname in _permissionnames)
|
||||||
{
|
{
|
||||||
<th style="text-align: center; width: 1px;">@((MarkupString)GetPermissionName(permission).Replace(" ", "<br />"))</th>
|
<th style="text-align: center; width: 1px;">@((MarkupString)DisplayPermissionName(permissionname).Replace(" ", "<br />"))</th>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
@foreach (Role role in _roles)
|
@foreach (Role role in _roles)
|
||||||
{
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>@role.Name</td>
|
<td>@role.Name</td>
|
||||||
@foreach (PermissionString permission in _permissions)
|
@foreach (var permissionname in _permissionnames)
|
||||||
{
|
{
|
||||||
var p = permission;
|
|
||||||
<td style="text-align: center;">
|
<td style="text-align: center;">
|
||||||
<TriStateCheckBox Value=@GetPermissionValue(p.Permissions, role.Name) Disabled="@GetPermissionDisabled(p.EntityName, p.PermissionName, role.Name)" OnChange="@(e => PermissionChanged(e, p.EntityName, p.PermissionName, role.Name))" />
|
<TriStateCheckBox Value=@GetPermissionValue(permissionname, role.Name, -1) Disabled="@GetPermissionDisabled(permissionname, role.Name)" OnChange="@(e => PermissionChanged(e, permissionname, role.Name, -1))" />
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
@ -50,23 +50,21 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">@Localizer["User"]</th>
|
<th scope="col">@Localizer["User"]</th>
|
||||||
@foreach (PermissionString permission in _permissions)
|
@foreach (var permissionname in _permissionnames)
|
||||||
{
|
{
|
||||||
<th style="text-align: center; width: 1px;">@Localizer[permission.PermissionName]</th>
|
<th style="text-align: center; width: 1px;">@((MarkupString)DisplayPermissionName(permissionname).Replace(" ", "<br />"))</th>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach (User user in _users)
|
@foreach (User user in _users)
|
||||||
{
|
{
|
||||||
string userid = "[" + user.UserId.ToString() + "]";
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>@user.DisplayName</td>
|
<td>@user.DisplayName</td>
|
||||||
@foreach (PermissionString permission in _permissions)
|
@foreach (var permissionname in _permissionnames)
|
||||||
{
|
{
|
||||||
var p = permission;
|
|
||||||
<td style="text-align: center; width: 1px;">
|
<td style="text-align: center; width: 1px;">
|
||||||
<TriStateCheckBox Value=@GetPermissionValue(p.Permissions, userid) Disabled="@GetPermissionDisabled(p.EntityName, p.PermissionName, "")" OnChange="@(e => PermissionChanged(e, p.EntityName, p.PermissionName, userid))" />
|
<TriStateCheckBox Value=@GetPermissionValue(permissionname, "", user.UserId) Disabled="@GetPermissionDisabled(permissionname, "")" OnChange="@(e => PermissionChanged(e, permissionname, "", user.UserId))" />
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
@ -94,9 +92,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string _permissionnames = string.Empty;
|
private List<string> _permissionnames;
|
||||||
|
private List<Permission> _permissions;
|
||||||
private List<Role> _roles;
|
private List<Role> _roles;
|
||||||
private List<PermissionString> _permissions;
|
|
||||||
private List<User> _users = new List<User>();
|
private List<User> _users = new List<User>();
|
||||||
private AutoComplete _user;
|
private AutoComplete _user;
|
||||||
private string _message = string.Empty;
|
private string _message = string.Empty;
|
||||||
@ -108,17 +106,16 @@
|
|||||||
public string PermissionNames { get; set; }
|
public string PermissionNames { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Permissions { get; set; }
|
public string Permissions { get; set; } // deprecated - use PermissionList instead
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public List<Permission> PermissionList { get; set; }
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(PermissionNames))
|
if (!string.IsNullOrEmpty(Permissions))
|
||||||
{
|
{
|
||||||
_permissionnames = Shared.PermissionNames.View + "," + Shared.PermissionNames.Edit;
|
PermissionList = JsonSerializer.Deserialize<List<Permission>>(Permissions);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_permissionnames = PermissionNames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_roles = await RoleService.GetRolesAsync(ModuleState.SiteId, true);
|
_roles = await RoleService.GetRolesAsync(ModuleState.SiteId, true);
|
||||||
@ -127,9 +124,37 @@
|
|||||||
_roles.RemoveAll(item => item.Name == RoleNames.Host);
|
_roles.RemoveAll(item => item.Name == RoleNames.Host);
|
||||||
}
|
}
|
||||||
|
|
||||||
_permissions = new List<PermissionString>();
|
// get permission names
|
||||||
|
if (string.IsNullOrEmpty(PermissionNames))
|
||||||
|
{
|
||||||
|
_permissionnames = new List<string>();
|
||||||
|
_permissionnames.Add(Shared.PermissionNames.View);
|
||||||
|
_permissionnames.Add(Shared.PermissionNames.Edit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_permissionnames = PermissionNames.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (string permissionname in _permissionnames.Split(',', StringSplitOptions.RemoveEmptyEntries))
|
// initialize permissions
|
||||||
|
_permissions = new List<Permission>();
|
||||||
|
if (PermissionList != null && PermissionList.Any())
|
||||||
|
{
|
||||||
|
foreach (var permission in PermissionList)
|
||||||
|
{
|
||||||
|
_permissions.Add(permission);
|
||||||
|
if (permission.UserId != null)
|
||||||
|
{
|
||||||
|
if (!_users.Any(item => item.UserId == permission.UserId.Value))
|
||||||
|
{
|
||||||
|
_users.Add(await UserService.GetUserAsync(permission.UserId.Value, ModuleState.SiteId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (string permissionname in _permissionnames)
|
||||||
{
|
{
|
||||||
// permission names can be in the form of "EntityName:PermissionName:Roles"
|
// permission names can be in the form of "EntityName:PermissionName:Roles"
|
||||||
if (permissionname.Contains(":"))
|
if (permissionname.Contains(":"))
|
||||||
@ -137,78 +162,65 @@
|
|||||||
var segments = permissionname.Split(':');
|
var segments = permissionname.Split(':');
|
||||||
if (segments.Length == 3)
|
if (segments.Length == 3)
|
||||||
{
|
{
|
||||||
if (!segments[2].Contains(RoleNames.Admin))
|
foreach (var role in segments[2].Split(';'))
|
||||||
{
|
{
|
||||||
segments[2] = RoleNames.Admin + ";" + segments[2]; // ensure admin access
|
_permissions.Add(new Permission(ModuleState.SiteId, segments[0], segments[1], role, null, true));
|
||||||
|
}
|
||||||
|
// ensure admin access
|
||||||
|
if (!_permissions.Any(item => item.EntityName == segments[0] && item.PermissionName == segments[1] && item.RoleName == RoleNames.Admin))
|
||||||
|
{
|
||||||
|
_permissions.Add(new Permission(ModuleState.SiteId, segments[0], segments[1], RoleNames.Admin, null, true));
|
||||||
}
|
}
|
||||||
_permissions.Add(new PermissionString { EntityName = segments[0], PermissionName = segments[1], Permissions = segments[2] });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_permissions.Add(new PermissionString { EntityName = EntityName, PermissionName = permissionname, Permissions = RoleNames.Admin });
|
_permissions.Add(new Permission(ModuleState.SiteId, EntityName, permissionname, RoleNames.Admin, null, true));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Permissions))
|
|
||||||
{
|
|
||||||
// populate permissions
|
|
||||||
foreach (PermissionString permissionstring in UserSecurity.GetPermissionStrings(Permissions))
|
|
||||||
{
|
|
||||||
int index = _permissions.FindIndex(item => item.EntityName == permissionstring.EntityName && item.PermissionName == permissionstring.PermissionName);
|
|
||||||
if (index != -1)
|
|
||||||
{
|
|
||||||
_permissions[index].Permissions = permissionstring.Permissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (permissionstring.Permissions.Contains("["))
|
|
||||||
{
|
|
||||||
foreach (string user in permissionstring.Permissions.Split('[', StringSplitOptions.RemoveEmptyEntries))
|
|
||||||
{
|
|
||||||
if (user.Contains("]"))
|
|
||||||
{
|
|
||||||
var userid = int.Parse(user.Substring(0, user.IndexOf("]")));
|
|
||||||
if (_users.Where(item => item.UserId == userid).FirstOrDefault() == null)
|
|
||||||
{
|
|
||||||
_users.Add(await UserService.GetUserAsync(userid, ModuleState.SiteId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetPermissionName(PermissionString permission)
|
private string GetPermissionName(string permissionName)
|
||||||
{
|
{
|
||||||
var permissionname = Localizer[permission.PermissionName].ToString();
|
return (permissionName.Contains(":")) ? permissionName.Split(':')[1] : permissionName;
|
||||||
if (!string.IsNullOrEmpty(EntityName))
|
|
||||||
{
|
|
||||||
permissionname += " " + Localizer[permission.EntityName].ToString();
|
|
||||||
}
|
|
||||||
return permissionname;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool? GetPermissionValue(string permissions, string securityKey)
|
private string GetEntityName(string permissionName)
|
||||||
{
|
{
|
||||||
if ((";" + permissions + ";").Contains(";" + "!" + securityKey + ";"))
|
return (permissionName.Contains(":")) ? permissionName.Split(':')[0] : EntityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string DisplayPermissionName(string permissionName)
|
||||||
{
|
{
|
||||||
return false; // deny permission
|
var name = Localizer[GetPermissionName(permissionName)].ToString();
|
||||||
|
name += " " + Localizer[GetEntityName(permissionName)].ToString();
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool? GetPermissionValue(string permissionName, string roleName, int userId)
|
||||||
|
{
|
||||||
|
bool? isauthorized = null;
|
||||||
|
if (roleName != "")
|
||||||
|
{
|
||||||
|
var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.RoleName == roleName);
|
||||||
|
if (permission != null)
|
||||||
|
{
|
||||||
|
isauthorized = permission.IsAuthorized;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((";" + permissions + ";").Contains(";" + securityKey + ";"))
|
var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.UserId == userId);
|
||||||
|
if (permission != null)
|
||||||
{
|
{
|
||||||
return true; // grant permission
|
isauthorized = permission.IsAuthorized;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null; // not specified
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return isauthorized;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool GetPermissionDisabled(string entityName, string permissionName, string roleName)
|
private bool GetPermissionDisabled(string permissionName, string roleName)
|
||||||
{
|
{
|
||||||
if (roleName == RoleNames.Admin && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
if (roleName == RoleNames.Admin && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
@ -216,7 +228,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (entityName != EntityName && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
if (GetEntityName(permissionName) != EntityName && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -227,6 +239,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PermissionChanged(bool? value, string permissionName, string roleName, int userId)
|
||||||
|
{
|
||||||
|
if (roleName != "")
|
||||||
|
{
|
||||||
|
var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.RoleName == roleName);
|
||||||
|
if (permission != null)
|
||||||
|
{
|
||||||
|
_permissions.Remove(permission);
|
||||||
|
}
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
_permissions.Add(new Permission(ModuleState.SiteId, GetEntityName(permissionName), GetPermissionName(permissionName), roleName, null, value.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.UserId == userId);
|
||||||
|
if (permission != null)
|
||||||
|
{
|
||||||
|
_permissions.Remove(permission);
|
||||||
|
}
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
_permissions.Add(new Permission(ModuleState.SiteId, GetEntityName(permissionName), GetPermissionName(permissionName), null, userId, value.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<Dictionary<string, string>> GetUsers(string filter)
|
private async Task<Dictionary<string, string>> GetUsers(string filter)
|
||||||
{
|
{
|
||||||
var users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered);
|
var users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered);
|
||||||
@ -251,62 +291,45 @@
|
|||||||
_user.Clear();
|
_user.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PermissionChanged(bool? value, string entityName, string permissionName, string securityId)
|
|
||||||
{
|
|
||||||
var selected = value;
|
|
||||||
int index = _permissions.FindIndex(item => item.EntityName == entityName && item.PermissionName == permissionName);
|
|
||||||
if (index != -1)
|
|
||||||
{
|
|
||||||
var permission = _permissions[index];
|
|
||||||
|
|
||||||
var ids = permission.Permissions.Split(';').ToList();
|
|
||||||
ids.Remove(securityId); // remove grant permission
|
|
||||||
ids.Remove("!" + securityId); // remove deny permission
|
|
||||||
|
|
||||||
switch (selected)
|
|
||||||
{
|
|
||||||
case true:
|
|
||||||
ids.Add(securityId); // add grant permission
|
|
||||||
break;
|
|
||||||
case false:
|
|
||||||
ids.Add("!" + securityId); // add deny permission
|
|
||||||
break;
|
|
||||||
case null:
|
|
||||||
break; // permission not specified
|
|
||||||
}
|
|
||||||
|
|
||||||
_permissions[index].Permissions = string.Join(";", ids.ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetPermissions()
|
public string GetPermissions()
|
||||||
{
|
{
|
||||||
ValidatePermissions();
|
ValidatePermissions();
|
||||||
return UserSecurity.SetPermissionStrings(_permissions);
|
return JsonSerializer.Serialize(_permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Permission> GetPermissionList()
|
||||||
|
{
|
||||||
|
ValidatePermissions();
|
||||||
|
return _permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ValidatePermissions()
|
private void ValidatePermissions()
|
||||||
{
|
{
|
||||||
PermissionString permission;
|
// remove deny all users, unauthenticated, and registered users
|
||||||
for (int index = 0; index < _permissions.Count; index++)
|
var permissions = _permissions.Where(item => !item.IsAuthorized &&
|
||||||
|
(item.RoleName == RoleNames.Everyone || item.RoleName == RoleNames.Unauthenticated || item.RoleName == RoleNames.Registered)).ToList();
|
||||||
|
foreach (var permission in permissions)
|
||||||
{
|
{
|
||||||
permission = _permissions[index];
|
_permissions.Remove(permission);
|
||||||
List<string> ids = permission.Permissions.Split(';', StringSplitOptions.RemoveEmptyEntries).ToList();
|
}
|
||||||
ids.Remove("!" + RoleNames.Everyone); // remove deny all users
|
|
||||||
ids.Remove("!" + RoleNames.Unauthenticated); // remove deny unauthenticated
|
|
||||||
ids.Remove("!" + RoleNames.Registered); // remove deny registered users
|
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
ids.Remove("!" + RoleNames.Admin); // remove deny administrators
|
// remove deny administrators and host users
|
||||||
ids.Remove("!" + RoleNames.Host); // remove deny host users
|
permissions = _permissions.Where(item => !item.IsAuthorized &&
|
||||||
if (!ids.Contains(RoleNames.Host) && !ids.Contains(RoleNames.Admin))
|
(item.RoleName == RoleNames.Admin || item.RoleName == RoleNames.Host)).ToList();
|
||||||
|
foreach (var permission in permissions)
|
||||||
{
|
{
|
||||||
// add administrators role if host user role is not assigned
|
_permissions.Remove(permission);
|
||||||
ids.Add(RoleNames.Admin);
|
}
|
||||||
|
foreach (var permissionname in _permissionnames)
|
||||||
|
{
|
||||||
|
// add administrators role if neither host or administrator is assigned
|
||||||
|
if (!_permissions.Any(item => item.EntityName == GetEntityName(permissionname) && item.PermissionName == GetPermissionName(permissionname) &&
|
||||||
|
(item.RoleName == RoleNames.Admin || item.RoleName == RoleNames.Host)))
|
||||||
|
{
|
||||||
|
_permissions.Add(new Permission(ModuleState.SiteId, GetEntityName(permissionname), GetPermissionName(permissionname), RoleNames.Admin, null, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
permission.Permissions = string.Join(";", ids.ToArray());
|
|
||||||
_permissions[index] = permission;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,10 +93,10 @@
|
|||||||
authorized = true;
|
authorized = true;
|
||||||
break;
|
break;
|
||||||
case SecurityAccessLevel.View:
|
case SecurityAccessLevel.View:
|
||||||
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, ModuleState.Permissions);
|
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, ModuleState.PermissionList);
|
||||||
break;
|
break;
|
||||||
case SecurityAccessLevel.Edit:
|
case SecurityAccessLevel.Edit:
|
||||||
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.Permissions);
|
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.PermissionList);
|
||||||
break;
|
break;
|
||||||
case SecurityAccessLevel.Admin:
|
case SecurityAccessLevel.Admin:
|
||||||
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin);
|
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin);
|
||||||
|
@ -190,12 +190,7 @@ namespace Oqtane.Modules
|
|||||||
|
|
||||||
public string AddUrlParameters(params object[] parameters)
|
public string AddUrlParameters(params object[] parameters)
|
||||||
{
|
{
|
||||||
var url = "";
|
return Utilities.AddUrlParameters(parameters);
|
||||||
for (var i = 0; i < parameters.Length; i++)
|
|
||||||
{
|
|
||||||
url += "/" + parameters[i].ToString();
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// template is in the form of a standard route template ie. "/{id}/{name}" and produces dictionary of key/value pairs
|
// template is in the form of a standard route template ie. "/{id}/{name}" and produces dictionary of key/value pairs
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RazorLangVersion>3.0</RazorLangVersion>
|
<RazorLangVersion>3.0</RazorLangVersion>
|
||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release</Configurations>
|
||||||
<Version>3.3.0</Version>
|
<Version>3.4.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<RootNamespace>Oqtane</RootNamespace>
|
<RootNamespace>Oqtane</RootNamespace>
|
||||||
|
@ -198,6 +198,8 @@ namespace Oqtane.Client
|
|||||||
private static void RegisterModuleServices(Assembly assembly, IServiceCollection services)
|
private static void RegisterModuleServices(Assembly assembly, IServiceCollection services)
|
||||||
{
|
{
|
||||||
// dynamically register module scoped services
|
// dynamically register module scoped services
|
||||||
|
try
|
||||||
|
{
|
||||||
var implementationTypes = assembly.GetInterfaces<IService>();
|
var implementationTypes = assembly.GetInterfaces<IService>();
|
||||||
foreach (var implementationType in implementationTypes)
|
foreach (var implementationType in implementationTypes)
|
||||||
{
|
{
|
||||||
@ -208,8 +210,15 @@ namespace Oqtane.Client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// could not interrogate assembly - likely missing dependencies
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void RegisterClientStartups(Assembly assembly, IServiceCollection services)
|
private static void RegisterClientStartups(Assembly assembly, IServiceCollection services)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var startUps = assembly.GetInstances<IClientStartup>();
|
var startUps = assembly.GetInstances<IClientStartup>();
|
||||||
foreach (var startup in startUps)
|
foreach (var startup in startUps)
|
||||||
@ -217,6 +226,11 @@ namespace Oqtane.Client
|
|||||||
startup.ConfigureServices(services);
|
startup.ConfigureServices(services);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// could not interrogate assembly - likely missing dependencies
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task SetCultureFromLocalizationCookie(IServiceProvider serviceProvider)
|
private static async Task SetCultureFromLocalizationCookie(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
|
@ -172,7 +172,7 @@
|
|||||||
<value>Enter a complete connection string including all parameters and delimiters</value>
|
<value>Enter a complete connection string including all parameters and delimiters</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ConnectionString.Text" xml:space="preserve">
|
<data name="ConnectionString.Text" xml:space="preserve">
|
||||||
<value>String:</value>
|
<value>Settings:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EnterConnectionParameters" xml:space="preserve">
|
<data name="EnterConnectionParameters" xml:space="preserve">
|
||||||
<value>Enter Connection Parameters</value>
|
<value>Enter Connection Parameters</value>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<root>
|
<root>
|
||||||
<!--
|
<!--
|
||||||
Microsoft ResX Schema
|
Microsoft ResX Schema
|
||||||
@ -193,6 +193,6 @@
|
|||||||
<value>Execute Once</value>
|
<value>Execute Once</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.NoJobs" xml:space="preserve">
|
<data name="Message.NoJobs" xml:space="preserve">
|
||||||
<value>Please Note That After An Initial Installation You Must &lt;a href={0}&gt;Restart&lt;/a&gt; The Application In Order To Activate The Default Scheduled Jobs.</value>
|
<value>Please Note That After An Initial Installation You Must <a href={0}>Restart</a> The Application In Order To Activate The Default Scheduled Jobs.</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
@ -120,29 +120,23 @@
|
|||||||
<data name="Error.Language.Add" xml:space="preserve">
|
<data name="Error.Language.Add" xml:space="preserve">
|
||||||
<value>Error Adding Language</value>
|
<value>Error Adding Language</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Translated.HelpText" xml:space="preserve">
|
|
||||||
<value>Specify If You Wish To Select Languages That Have Translations Installed</value>
|
|
||||||
</data>
|
|
||||||
<data name="Name.HelpText" xml:space="preserve">
|
<data name="Name.HelpText" xml:space="preserve">
|
||||||
<value>Name Of The Langauage</value>
|
<value>Name Of The Langauage</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IsDefault.HelpText" xml:space="preserve">
|
<data name="IsDefault.HelpText" xml:space="preserve">
|
||||||
<value>Indicates Whether Or Not This Language Is The Default For The Site</value>
|
<value>Indicates Whether Or Not This Language Is The Default For The Site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Translated.Text" xml:space="preserve">
|
|
||||||
<value>Translated?</value>
|
|
||||||
</data>
|
|
||||||
<data name="Name.Text" xml:space="preserve">
|
<data name="Name.Text" xml:space="preserve">
|
||||||
<value>Name:</value>
|
<value>Name:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IsDefault.Text" xml:space="preserve">
|
<data name="IsDefault.Text" xml:space="preserve">
|
||||||
<value>Default?</value>
|
<value>Default?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Language.Install" xml:space="preserve">
|
<data name="Success.Language.Download" xml:space="preserve">
|
||||||
<value>Translations Installed Successfully. You Must <a href={0}>Restart</a> Your Application To Apply These Changes.</value>
|
<value>Translation Package Saved Successfully. You Must <a href={0}>Restart</a> To Complete The Installation.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LanguageUpload.HelpText" xml:space="preserve">
|
<data name="LanguageUpload.HelpText" xml:space="preserve">
|
||||||
<value>Upload one or more translation packages. Once they are uploaded click Install to complete the installation.</value>
|
<value>Upload one or more translation packages.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LanguageUpload.Text" xml:space="preserve">
|
<data name="LanguageUpload.Text" xml:space="preserve">
|
||||||
<value>Translation</value>
|
<value>Translation</value>
|
||||||
|
@ -132,12 +132,12 @@
|
|||||||
<data name="DeleteLanguage.Header" xml:space="preserve">
|
<data name="DeleteLanguage.Header" xml:space="preserve">
|
||||||
<value>Delete Language</value>
|
<value>Delete Language</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Success.Language.Download" xml:space="preserve">
|
||||||
|
<value>Translation Package Saved Successfully. You Must <a href={0}>Restart</a> Your Application To Complete The Installation.</value>
|
||||||
|
</data>
|
||||||
<data name="Error.Language.Download" xml:space="preserve">
|
<data name="Error.Language.Download" xml:space="preserve">
|
||||||
<value>Error Downloading Translation</value>
|
<value>Error Downloading Translation</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Language.Install" xml:space="preserve">
|
|
||||||
<value>Translation Installed Successfully. You Must <a href={0}>Restart</a> Your Application To Apply These Changes.</value>
|
|
||||||
</data>
|
|
||||||
<data name="Default" xml:space="preserve">
|
<data name="Default" xml:space="preserve">
|
||||||
<value>Default</value>
|
<value>Default</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -123,17 +123,14 @@
|
|||||||
<data name="Error.Package.Load" xml:space="preserve">
|
<data name="Error.Package.Load" xml:space="preserve">
|
||||||
<value>Error Loading Packages</value>
|
<value>Error Loading Packages</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Module.Install" xml:space="preserve">
|
|
||||||
<value>Module Installed Successfully. You Must <a href={0}>Restart</a> Your Application To Apply These Changes.</value>
|
|
||||||
</data>
|
|
||||||
<data name="Success.Module.Download" xml:space="preserve">
|
<data name="Success.Module.Download" xml:space="preserve">
|
||||||
<value>Module Downloaded Successfully. Click Install To Complete Installation.</value>
|
<value>Module Package Saved Successfully. You Must <a href={0}>Restart</a> Your Application To Complete The Installation.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.Module.Download" xml:space="preserve">
|
<data name="Error.Module.Download" xml:space="preserve">
|
||||||
<value>Error Downloading Module</value>
|
<value>Error Downloading Module</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Module.HelpText" xml:space="preserve">
|
<data name="Module.HelpText" xml:space="preserve">
|
||||||
<value>Upload one or more module packages. Once they are uploaded click Install to complete the installation.</value>
|
<value>Upload one or more module packages.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.NoResults" xml:space="preserve">
|
<data name="Search.NoResults" xml:space="preserve">
|
||||||
<value>No Modules Match The Criteria Provided Or Package Service Is Disabled</value>
|
<value>No Modules Match The Criteria Provided Or Package Service Is Disabled</value>
|
||||||
|
@ -211,12 +211,12 @@
|
|||||||
<value>No Translations Exist For This Module Or Package Service Is Disabled</value>
|
<value>No Translations Exist For This Module Or Package Service Is Disabled</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Translation.Download" xml:space="preserve">
|
<data name="Success.Translation.Download" xml:space="preserve">
|
||||||
<value>Translation Downloaded Successfully. Click Install To Complete Installation.</value>
|
<value>Translation Package Saved Successfully. You Must <a href={0}>Restart</a> Your Application To Complete The Installation.</value>
|
||||||
</data>
|
|
||||||
<data name="Success.Translation.Install" xml:space="preserve">
|
|
||||||
<value>Translation Installed Successfully. You Must <a href={0}>Restart</a> Your Application To Apply These Changes.</value>
|
|
||||||
</data>
|
</data>
|
||||||
<data name="Translations.Heading" xml:space="preserve">
|
<data name="Translations.Heading" xml:space="preserve">
|
||||||
<value>Translations</value>
|
<value>Translations</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Message.DuplicateName" xml:space="preserve">
|
||||||
|
<value>A Module With The Name Specified Already Exists</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<root>
|
<root>
|
||||||
<!--
|
<!--
|
||||||
Microsoft ResX Schema
|
Microsoft ResX Schema
|
||||||
@ -166,7 +166,7 @@
|
|||||||
<value>Email:</value>
|
<value>Email:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Password.HelpText" xml:space="preserve">
|
<data name="Password.HelpText" xml:space="preserve">
|
||||||
<value>Please choose a sufficiently secure password and enter it here</value>
|
<value>Please enter a sufficiently secure password which meets the password complexity requirements</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Password.Text" xml:space="preserve">
|
<data name="Password.Text" xml:space="preserve">
|
||||||
<value>Password:</value>
|
<value>Password:</value>
|
||||||
@ -177,4 +177,19 @@
|
|||||||
<data name="Username.Text" xml:space="preserve">
|
<data name="Username.Text" xml:space="preserve">
|
||||||
<value>Username:</value>
|
<value>Username:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Password.ValidationCriteria" xml:space="preserve">
|
||||||
|
<value>Passwords Must Have A Minimum Length Of {0} Characters, Including At Least {1} Unique Character(s), {2}{3}{4}{5} To Satisfy Password Compexity Requirements For This Site.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Password.DigitRequirement" xml:space="preserve">
|
||||||
|
<value>At Least One Digit</value>
|
||||||
|
</data>
|
||||||
|
<data name="Password.LowercaseRequirement" xml:space="preserve">
|
||||||
|
<value>At Least One Lowercase Letter</value>
|
||||||
|
</data>
|
||||||
|
<data name="Password.PunctuationRequirement" xml:space="preserve">
|
||||||
|
<value>At Least One Punctuation Mark</value>
|
||||||
|
</data>
|
||||||
|
<data name="Password.UppercaseRequirement" xml:space="preserve">
|
||||||
|
<value>At Least One Uppercase Letter</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -163,7 +163,7 @@
|
|||||||
<value>Enter the site name</value>
|
<value>Enter the site name</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Tenant.HelpText" xml:space="preserve">
|
<data name="Tenant.HelpText" xml:space="preserve">
|
||||||
<value>Enter the tenant for the site</value>
|
<value>The name of the database used for the site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Aliases.HelpText" xml:space="preserve">
|
<data name="Aliases.HelpText" xml:space="preserve">
|
||||||
<value>The aliases for the site. An alias can be a domain name (www.site.com) or a virtual folder (ie. www.site.com/folder).</value>
|
<value>The aliases for the site. An alias can be a domain name (www.site.com) or a virtual folder (ie. www.site.com/folder).</value>
|
||||||
@ -214,7 +214,7 @@
|
|||||||
<value>Include a splash icon for your PWA. It should be a PNG which is 512 X 512 pixels in dimension.</value>
|
<value>Include a splash icon for your PWA. It should be a PNG which is 512 X 512 pixels in dimension.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Tenant.Text" xml:space="preserve">
|
<data name="Tenant.Text" xml:space="preserve">
|
||||||
<value>Tenant: </value>
|
<value>Database: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Aliases.Text" xml:space="preserve">
|
<data name="Aliases.Text" xml:space="preserve">
|
||||||
<value>Aliases: </value>
|
<value>Aliases: </value>
|
||||||
@ -292,7 +292,7 @@
|
|||||||
<value>Browse</value>
|
<value>Browse</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TenantInformation.Heading" xml:space="preserve">
|
<data name="TenantInformation.Heading" xml:space="preserve">
|
||||||
<value>Tenant Information</value>
|
<value>Database</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PWASettings.Heading" xml:space="preserve">
|
<data name="PWASettings.Heading" xml:space="preserve">
|
||||||
<value>PWA Settings</value>
|
<value>PWA Settings</value>
|
||||||
@ -304,13 +304,13 @@
|
|||||||
<value>Connection:</value>
|
<value>Connection:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Database.Text" xml:space="preserve">
|
<data name="Database.Text" xml:space="preserve">
|
||||||
<value>Database:</value>
|
<value>Type:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ConnectionString.HelpText" xml:space="preserve">
|
<data name="ConnectionString.HelpText" xml:space="preserve">
|
||||||
<value>The connection information for the database</value>
|
<value>The connection information for the database</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Database.HelpText" xml:space="preserve">
|
<data name="Database.HelpText" xml:space="preserve">
|
||||||
<value>The database for the tenant</value>
|
<value>The type of database</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DeleteSite.Text" xml:space="preserve">
|
<data name="DeleteSite.Text" xml:space="preserve">
|
||||||
<value>Delete Site</value>
|
<value>Delete Site</value>
|
||||||
@ -345,4 +345,10 @@
|
|||||||
<data name="SmtpRelay.Text" xml:space="preserve">
|
<data name="SmtpRelay.Text" xml:space="preserve">
|
||||||
<value>Relay Configured?</value>
|
<value>Relay Configured?</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="SiteMap.HelpText" xml:space="preserve">
|
||||||
|
<value>The site map url for this site which can be submitted to search engines for indexing</value>
|
||||||
|
</data>
|
||||||
|
<data name="SiteMap.Text" xml:space="preserve">
|
||||||
|
<value>Site Map:</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -123,9 +123,6 @@
|
|||||||
<data name="SqlServer" xml:space="preserve">
|
<data name="SqlServer" xml:space="preserve">
|
||||||
<value>SQL Server</value>
|
<value>SQL Server</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Server.Text" xml:space="preserve">
|
|
||||||
<value>Server: </value>
|
|
||||||
</data>
|
|
||||||
<data name="Container.Select" xml:space="preserve">
|
<data name="Container.Select" xml:space="preserve">
|
||||||
<value>Select Container</value>
|
<value>Select Container</value>
|
||||||
</data>
|
</data>
|
||||||
@ -145,7 +142,7 @@
|
|||||||
<value>Select the default container for the site</value>
|
<value>Select the default container for the site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Tenant.Text" xml:space="preserve">
|
<data name="Tenant.Text" xml:space="preserve">
|
||||||
<value>Tenant: </value>
|
<value>Database: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Aliases.Text" xml:space="preserve">
|
<data name="Aliases.Text" xml:space="preserve">
|
||||||
<value>Aliases: </value>
|
<value>Aliases: </value>
|
||||||
@ -157,10 +154,10 @@
|
|||||||
<value>Select Site Template</value>
|
<value>Select Site Template</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Tenant.Select" xml:space="preserve">
|
<data name="Tenant.Select" xml:space="preserve">
|
||||||
<value>Select Tenant</value>
|
<value>Select Database</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Tenant.Add" xml:space="preserve">
|
<data name="Tenant.Add" xml:space="preserve">
|
||||||
<value>Create New Tenant</value>
|
<value>Create Database</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.Theme.LoadContainers" xml:space="preserve">
|
<data name="Error.Theme.LoadContainers" xml:space="preserve">
|
||||||
<value>Error Loading Containers For Theme</value>
|
<value>Error Loading Containers For Theme</value>
|
||||||
@ -172,19 +169,19 @@
|
|||||||
<value>Invalid Host Password</value>
|
<value>Invalid Host Password</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.TenantName.Exists" xml:space="preserve">
|
<data name="Error.TenantName.Exists" xml:space="preserve">
|
||||||
<value>Tenant Name Is Missing Or Already Exists</value>
|
<value>Database Name Is Missing Or Already Exists</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.SiteName.InUse" xml:space="preserve">
|
<data name="Message.SiteName.InUse" xml:space="preserve">
|
||||||
<value>{0} Already Used For Another Site</value>
|
<value>{0} Already Used For Another Site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Required.Tenant" xml:space="preserve">
|
<data name="Message.Required.Tenant" xml:space="preserve">
|
||||||
<value>You Must Provide A Tenant, Site Name, Alias, Default Theme/Container, And Site Template</value>
|
<value>You Must Provide A Database, Site Name, Alias, Default Theme/Container, And Site Template</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Name.HelpText" xml:space="preserve">
|
<data name="Name.HelpText" xml:space="preserve">
|
||||||
<value>Enter the name of the site</value>
|
<value>Enter the name of the site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DefaultTheme.HelpText" xml:space="preserve">
|
<data name="DefaultTheme.HelpText" xml:space="preserve">
|
||||||
<value>Select the default theme for the website</value>
|
<value>Select the default theme for the site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AdminContainer.HelpText" xml:space="preserve">
|
<data name="AdminContainer.HelpText" xml:space="preserve">
|
||||||
<value>Select the admin container for the site</value>
|
<value>Select the admin container for the site</value>
|
||||||
@ -193,28 +190,13 @@
|
|||||||
<value>Select the site template</value>
|
<value>Select the site template</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Tenant.HelpText" xml:space="preserve">
|
<data name="Tenant.HelpText" xml:space="preserve">
|
||||||
<value>Select the tenant for the site</value>
|
<value>Select the database for the site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TenantName.HelpText" xml:space="preserve">
|
<data name="TenantName.HelpText" xml:space="preserve">
|
||||||
<value>Enter the name for the tenant</value>
|
<value>Enter the name for the database</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DatabaseType.HelpText" xml:space="preserve">
|
<data name="DatabaseType.HelpText" xml:space="preserve">
|
||||||
<value>Select the database type for the tenant</value>
|
<value>Select the database type</value>
|
||||||
</data>
|
|
||||||
<data name="DatabaseServer.HelpText" xml:space="preserve">
|
|
||||||
<value>Enter the server for the tenant</value>
|
|
||||||
</data>
|
|
||||||
<data name="Database.HelpText" xml:space="preserve">
|
|
||||||
<value>Enter the database for the tenant</value>
|
|
||||||
</data>
|
|
||||||
<data name="IntegratedSecurity.HelpText" xml:space="preserve">
|
|
||||||
<value>Select if you want integrated security or not</value>
|
|
||||||
</data>
|
|
||||||
<data name="DatabaseUsername.HelpText" xml:space="preserve">
|
|
||||||
<value>Enter the username for the integrated security</value>
|
|
||||||
</data>
|
|
||||||
<data name="DatabasePassword.HelpText" xml:space="preserve">
|
|
||||||
<value>Enter the password for the integrated security</value>
|
|
||||||
</data>
|
</data>
|
||||||
<data name="HostUsername.HelpText" xml:space="preserve">
|
<data name="HostUsername.HelpText" xml:space="preserve">
|
||||||
<value>Enter the username of an existing host user</value>
|
<value>Enter the username of an existing host user</value>
|
||||||
@ -232,23 +214,14 @@
|
|||||||
<value>Site Template: </value>
|
<value>Site Template: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TenantName.Text" xml:space="preserve">
|
<data name="TenantName.Text" xml:space="preserve">
|
||||||
<value>Tenant Name: </value>
|
<value>Name: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DatabaseType.Text" xml:space="preserve">
|
<data name="DatabaseType.Text" xml:space="preserve">
|
||||||
<value>Database Type: </value>
|
<value>Type: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Database.Text" xml:space="preserve">
|
<data name="Database.Text" xml:space="preserve">
|
||||||
<value>Database: </value>
|
<value>Database: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IntegratedSecurity.Text" xml:space="preserve">
|
|
||||||
<value>Integrated Security: </value>
|
|
||||||
</data>
|
|
||||||
<data name="DatabaseUsername.Text" xml:space="preserve">
|
|
||||||
<value>Database Username: </value>
|
|
||||||
</data>
|
|
||||||
<data name="DatabasePassword.Text" xml:space="preserve">
|
|
||||||
<value>Database Password: </value>
|
|
||||||
</data>
|
|
||||||
<data name="HostUsername.Text" xml:space="preserve">
|
<data name="HostUsername.Text" xml:space="preserve">
|
||||||
<value>Host Username:</value>
|
<value>Host Username:</value>
|
||||||
</data>
|
</data>
|
||||||
@ -274,7 +247,7 @@
|
|||||||
<value>Enter a complete connection string including all parameters and delimiters</value>
|
<value>Enter a complete connection string including all parameters and delimiters</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ConnectionString.Text" xml:space="preserve">
|
<data name="ConnectionString.Text" xml:space="preserve">
|
||||||
<value>String:</value>
|
<value>Settings:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EnterConnectionParameters" xml:space="preserve">
|
<data name="EnterConnectionParameters" xml:space="preserve">
|
||||||
<value>Enter Connection Parameters</value>
|
<value>Enter Connection Parameters</value>
|
||||||
|
@ -117,30 +117,75 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="Tenant.Text" xml:space="preserve">
|
<data name="Connection.Text" xml:space="preserve">
|
||||||
<value>Tenant: </value>
|
<value>Connection: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Tenant.Select" xml:space="preserve">
|
<data name="Connection.HelpText" xml:space="preserve">
|
||||||
<value>Select Tenant</value>
|
<value>Select a database connection (from appsettings.json)</value>
|
||||||
|
</data>
|
||||||
|
<data name="Connection.Select" xml:space="preserve">
|
||||||
|
<value>Select Connection</value>
|
||||||
|
</data>
|
||||||
|
<data name="Connection.Add" xml:space="preserve">
|
||||||
|
<value>Add Connection</value>
|
||||||
|
</data>
|
||||||
|
<data name="Name.Text" xml:space="preserve">
|
||||||
|
<value>Name: </value>
|
||||||
|
</data>
|
||||||
|
<data name="Name.HelpText" xml:space="preserve">
|
||||||
|
<value>Enter the name of the connection</value>
|
||||||
|
</data>
|
||||||
|
<data name="DatabaseType.Text" xml:space="preserve">
|
||||||
|
<value>Type: </value>
|
||||||
|
</data>
|
||||||
|
<data name="DatabaseType.HelpText" xml:space="preserve">
|
||||||
|
<value>Select the database type</value>
|
||||||
|
</data>
|
||||||
|
<data name="Type.Select" xml:space="preserve">
|
||||||
|
<value>Select Type</value>
|
||||||
|
</data>
|
||||||
|
<data name="EnterConnectionParameters" xml:space="preserve">
|
||||||
|
<value>Enter Connection Parameters</value>
|
||||||
|
</data>
|
||||||
|
<data name="EnterConnectionString" xml:space="preserve">
|
||||||
|
<value>Enter Connection String</value>
|
||||||
|
</data>
|
||||||
|
<data name="ConnectionString.Text" xml:space="preserve">
|
||||||
|
<value>Settings: </value>
|
||||||
|
</data>
|
||||||
|
<data name="ConnectionString.HelpText" xml:space="preserve">
|
||||||
|
<value>A complete connection string including all parameters and delimiters</value>
|
||||||
|
</data>
|
||||||
|
<data name="Add" xml:space="preserve">
|
||||||
|
<value>Add</value>
|
||||||
|
</data>
|
||||||
|
<data name="Tenant.Text" xml:space="preserve">
|
||||||
|
<value>Database: </value>
|
||||||
|
</data>
|
||||||
|
<data name="Tenant.HelpText" xml:space="preserve">
|
||||||
|
<value>The database using this connection</value>
|
||||||
|
</data>
|
||||||
|
<data name="SqlQuery.Text" xml:space="preserve">
|
||||||
|
<value>SQL Query: </value>
|
||||||
|
</data>
|
||||||
|
<data name="SqlQuery.HelpText" xml:space="preserve">
|
||||||
|
<value>Enter a valid SQL query for the database</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Execute" xml:space="preserve">
|
<data name="Execute" xml:space="preserve">
|
||||||
<value>Execute</value>
|
<value>Execute</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Required.Tenant" xml:space="preserve">
|
<data name="Message.Required.Tenant" xml:space="preserve">
|
||||||
<value>You Must Select A Tenant And Provide A Valid SQL Query</value>
|
<value>You Must Select A Database Type And Provide A Valid SQL Query</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Required.Connection" xml:space="preserve">
|
||||||
|
<value>You Must Provide A Connection Name And Settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Connection.Added" xml:space="preserve">
|
||||||
|
<value>Connection Added Successfully</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Return.NoResult" xml:space="preserve">
|
<data name="Return.NoResult" xml:space="preserve">
|
||||||
<value>No Results Returned</value>
|
<value>No Results Returned</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Tenant.HelpText" xml:space="preserve">
|
|
||||||
<value>Select the tenant associated with the database server</value>
|
|
||||||
</data>
|
|
||||||
<data name="SqlQuery.HelpText" xml:space="preserve">
|
|
||||||
<value>Enter the SQL query for the database server</value>
|
|
||||||
</data>
|
|
||||||
<data name="SqlQuery.Text" xml:space="preserve">
|
|
||||||
<value>SQL Query: </value>
|
|
||||||
</data>
|
|
||||||
<data name="Success.QueryExecuted" xml:space="preserve">
|
<data name="Success.QueryExecuted" xml:space="preserve">
|
||||||
<value>SQL Query Executed</value>
|
<value>SQL Query Executed</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -285,4 +285,13 @@
|
|||||||
<data name="Log.HelpText" xml:space="preserve">
|
<data name="Log.HelpText" xml:space="preserve">
|
||||||
<value>System log information for current day</value>
|
<value>System log information for current day</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Clear" xml:space="preserve">
|
||||||
|
<value>Clear</value>
|
||||||
|
</data>
|
||||||
|
<data name="Success.ClearLog" xml:space="preserve">
|
||||||
|
<value>System Log Has Been Successfully Cleared</value>
|
||||||
|
</data>
|
||||||
|
<data name="Error.ClearLog" xml:space="preserve">
|
||||||
|
<value>Ann Error Occurred Clearing The System Log</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -123,17 +123,14 @@
|
|||||||
<data name="Theme.Text" xml:space="preserve">
|
<data name="Theme.Text" xml:space="preserve">
|
||||||
<value>Theme: </value>
|
<value>Theme: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Theme.Install" xml:space="preserve">
|
|
||||||
<value>Theme Installed Successfully. You Must <a href={0}>Restart</a> Your Application To Apply These Changes.</value>
|
|
||||||
</data>
|
|
||||||
<data name="Success.Theme.Download" xml:space="preserve">
|
<data name="Success.Theme.Download" xml:space="preserve">
|
||||||
<value>Theme Downloaded Successfully. Click Install To Complete Installation.</value>
|
<value>Theme Package Saved Successfully. You Must <a href={0}>Restart</a> Your Application To Complete The Installation.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.Theme.Download" xml:space="preserve">
|
<data name="Error.Theme.Download" xml:space="preserve">
|
||||||
<value>Error Downloading Theme</value>
|
<value>Error Downloading Theme</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Theme.HelpText" xml:space="preserve">
|
<data name="Theme.HelpText" xml:space="preserve">
|
||||||
<value>Upload one or more theme packages. Once they are uploaded click Install to complete the installation.</value>
|
<value>Upload one or more theme packages.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.NoResults" xml:space="preserve">
|
<data name="Search.NoResults" xml:space="preserve">
|
||||||
<value>No Themes Match The Criteria Provided Or Package Service Is Disabled</value>
|
<value>No Themes Match The Criteria Provided Or Package Service Is Disabled</value>
|
||||||
|
@ -388,6 +388,12 @@
|
|||||||
<value>Optionally provide the name of the role claim provided by the identity provider. These roles will be used in addition to any internal user roles assigned within the site.</value>
|
<value>Optionally provide the name of the role claim provided by the identity provider. These roles will be used in addition to any internal user roles assigned within the site.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RoleClaimType.Text" xml:space="preserve">
|
<data name="RoleClaimType.Text" xml:space="preserve">
|
||||||
<value>Role Claim Type:</value>
|
<value>Role Claim:</value>
|
||||||
|
</data>
|
||||||
|
<data name="ProfileClaimTypes.HelpText" xml:space="preserve">
|
||||||
|
<value>Optionally provide a comma delimited list of user profile claims provided by the identity provider, as well as mappings to your user profile definition. For example if the identity provider includes a 'given_name' claim and you have a 'FirstName' user profile definition you should specify 'given_name:FirstName'.</value>
|
||||||
|
</data>
|
||||||
|
<data name="ProfileClaimTypes.Text" xml:space="preserve">
|
||||||
|
<value>User Profile Claims:</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
@ -340,6 +340,48 @@
|
|||||||
<value>Visitor Management</value>
|
<value>Visitor Management</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Oqtane.Marketplace" xml:space="preserve">
|
<data name="Oqtane.Marketplace" xml:space="preserve">
|
||||||
<value>Please note that the third party extensions displayed above have been registered in the <a href="https://www.oqtane.net" target="_new">Oqtane Marketplace</a> which enables them to be seamlessly downloaded and installed into the framework.</value>
|
<value>Please note that third party extensions are registered in the <a href="https://www.oqtane.net" target="_new">Oqtane Marketplace</a> which enables them to be seamlessly downloaded and installed into the framework.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Home" xml:space="preserve">
|
||||||
|
<value>Home</value>
|
||||||
|
</data>
|
||||||
|
<data name="Close" xml:space="preserve">
|
||||||
|
<value>Close</value>
|
||||||
|
</data>
|
||||||
|
<data name="OK" xml:space="preserve">
|
||||||
|
<value>OK</value>
|
||||||
|
</data>
|
||||||
|
<data name="Apply" xml:space="preserve">
|
||||||
|
<value>Apply</value>
|
||||||
|
</data>
|
||||||
|
<data name="Select" xml:space="preserve">
|
||||||
|
<value>Select</value>
|
||||||
|
</data>
|
||||||
|
<data name="Next" xml:space="preserve">
|
||||||
|
<value>Next</value>
|
||||||
|
</data>
|
||||||
|
<data name="Previous" xml:space="preserve">
|
||||||
|
<value>Previous</value>
|
||||||
|
</data>
|
||||||
|
<data name="Submit" xml:space="preserve">
|
||||||
|
<value>Submit</value>
|
||||||
|
</data>
|
||||||
|
<data name="Refresh" xml:space="preserve">
|
||||||
|
<value>Refresh</value>
|
||||||
|
</data>
|
||||||
|
<data name="Back" xml:space="preserve">
|
||||||
|
<value>Back</value>
|
||||||
|
</data>
|
||||||
|
<data name="Return" xml:space="preserve">
|
||||||
|
<value>Return</value>
|
||||||
|
</data>
|
||||||
|
<data name="New" xml:space="preserve">
|
||||||
|
<value>New</value>
|
||||||
|
</data>
|
||||||
|
<data name="View" xml:space="preserve">
|
||||||
|
<value>View</value>
|
||||||
|
</data>
|
||||||
|
<data name="Confirm" xml:space="preserve">
|
||||||
|
<value>Confirm</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
@ -33,13 +33,6 @@ namespace Oqtane.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task UpdateModuleDefinitionAsync(ModuleDefinition moduleDefinition);
|
Task UpdateModuleDefinitionAsync(ModuleDefinition moduleDefinition);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Installs all module definitions located in //TODO: 2dm where?
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task InstallModuleDefinitionsAsync();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes a module definition
|
/// Deletes a module definition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -62,7 +62,7 @@ namespace Oqtane.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a key-value dictionary of all page module settings for the given page module
|
/// Returns a key-value dictionary of all page module settings for the given page module
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pageId"></param>
|
/// <param name="pageModuleId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<Dictionary<string, string>> GetPageModuleSettingsAsync(int pageModuleId);
|
Task<Dictionary<string, string>> GetPageModuleSettingsAsync(int pageModuleId);
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ namespace Oqtane.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a key-value dictionary of all user settings for the given user
|
/// Returns a key-value dictionary of all user settings for the given user
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pageId"></param>
|
/// <param name="userId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<Dictionary<string, string>> GetUserSettingsAsync(int userId);
|
Task<Dictionary<string, string>> GetUserSettingsAsync(int userId);
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ namespace Oqtane.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a key-value dictionary of all folder settings for the given folder
|
/// Returns a key-value dictionary of all folder settings for the given folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pageId"></param>
|
/// <param name="folderId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<Dictionary<string, string>> GetFolderSettingsAsync(int folderId);
|
Task<Dictionary<string, string>> GetFolderSettingsAsync(int folderId);
|
||||||
|
|
||||||
@ -148,6 +148,21 @@ namespace Oqtane.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task UpdateHostSettingsAsync(Dictionary<string, string> hostSettings);
|
Task UpdateHostSettingsAsync(Dictionary<string, string> hostSettings);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a key-value dictionary of all settings for the given visitor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="visitorId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<Dictionary<string, string>> GetVisitorSettingsAsync(int visitorId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates a visitor setting
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="visitorSettings"></param>
|
||||||
|
/// <param name="visitorId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task UpdateVisitorSettingsAsync(Dictionary<string, string> visitorSettings, int visitorId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a key-value dictionary of all settings for the given entityName
|
/// Returns a key-value dictionary of all settings for the given entityName
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -32,11 +32,5 @@ namespace Oqtane.Services
|
|||||||
/// <param name="settings"></param>
|
/// <param name="settings"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task UpdateSystemInfoAsync(Dictionary<string, object> settings);
|
Task UpdateSystemInfoAsync(Dictionary<string, object> settings);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// updates a config value
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task UpdateSystemInfoAsync(string settingKey, object settingValue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,6 @@ namespace Oqtane.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
List<ThemeControl> GetContainerControls(List<Theme> themes, string themeName);
|
List<ThemeControl> GetContainerControls(List<Theme> themes, string themeName);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Installs all themes located in //TODO: 2dm where?
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task InstallThemesAsync();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes a theme
|
/// Deletes a theme
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -34,11 +34,6 @@ namespace Oqtane.Services
|
|||||||
await PutJsonAsync($"{Apiurl}/{moduleDefinition.ModuleDefinitionId}", moduleDefinition);
|
await PutJsonAsync($"{Apiurl}/{moduleDefinition.ModuleDefinitionId}", moduleDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InstallModuleDefinitionsAsync()
|
|
||||||
{
|
|
||||||
await GetJsonAsync<List<string>>($"{Apiurl}/install");
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteModuleDefinitionAsync(int moduleDefinitionId, int siteId)
|
public async Task DeleteModuleDefinitionAsync(int moduleDefinitionId, int siteId)
|
||||||
{
|
{
|
||||||
await DeleteAsync($"{Apiurl}/{moduleDefinitionId}?siteid={siteId}");
|
await DeleteAsync($"{Apiurl}/{moduleDefinitionId}?siteid={siteId}");
|
||||||
|
@ -18,11 +18,7 @@ namespace Oqtane.Services
|
|||||||
|
|
||||||
public async Task<List<Module>> GetModulesAsync(int siteId)
|
public async Task<List<Module>> GetModulesAsync(int siteId)
|
||||||
{
|
{
|
||||||
List<Module> modules = await GetJsonAsync<List<Module>>($"{Apiurl}?siteid={siteId}");
|
return await GetJsonAsync<List<Module>>($"{Apiurl}?siteid={siteId}");
|
||||||
modules = modules
|
|
||||||
.OrderBy(item => item.Order)
|
|
||||||
.ToList();
|
|
||||||
return modules;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Module> GetModuleAsync(int moduleId)
|
public async Task<Module> GetModuleAsync(int moduleId)
|
||||||
|
@ -111,15 +111,37 @@ namespace Oqtane.Services
|
|||||||
await UpdateSettingsAsync(hostSettings, EntityNames.Host, -1);
|
await UpdateSettingsAsync(hostSettings, EntityNames.Host, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Dictionary<string, string>> GetVisitorSettingsAsync(int visitorId)
|
||||||
|
{
|
||||||
|
if (visitorId != -1)
|
||||||
|
{
|
||||||
|
return await GetSettingsAsync(EntityNames.Visitor, visitorId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new Dictionary<string, string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateVisitorSettingsAsync(Dictionary<string, string> visitorSettings, int visitorId)
|
||||||
|
{
|
||||||
|
if (visitorId != -1)
|
||||||
|
{
|
||||||
|
await UpdateSettingsAsync(visitorSettings, EntityNames.Visitor, visitorId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<string, string>> GetSettingsAsync(string entityName, int entityId)
|
public async Task<Dictionary<string, string>> GetSettingsAsync(string entityName, int entityId)
|
||||||
{
|
{
|
||||||
var dictionary = new Dictionary<string, string>();
|
var dictionary = new Dictionary<string, string>();
|
||||||
var settings = await GetJsonAsync<List<Setting>>($"{Apiurl}?entityname={entityName}&entityid={entityId}");
|
var settings = await GetJsonAsync<List<Setting>>($"{Apiurl}?entityname={entityName}&entityid={entityId}");
|
||||||
|
if (settings != null)
|
||||||
|
{
|
||||||
foreach (Setting setting in settings.OrderBy(item => item.SettingName).ToList())
|
foreach (Setting setting in settings.OrderBy(item => item.SettingName).ToList())
|
||||||
{
|
{
|
||||||
dictionary.Add(setting.SettingName, setting.SettingValue);
|
dictionary.Add(setting.SettingName, setting.SettingValue);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return dictionary;
|
return dictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Oqtane.Documentation;
|
using Oqtane.Documentation;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
namespace Oqtane.Services
|
namespace Oqtane.Services
|
||||||
{
|
{
|
||||||
@ -32,9 +33,5 @@ namespace Oqtane.Services
|
|||||||
{
|
{
|
||||||
await PostJsonAsync(Apiurl, settings);
|
await PostJsonAsync(Apiurl, settings);
|
||||||
}
|
}
|
||||||
public async Task UpdateSystemInfoAsync(string settingKey, object settingValue)
|
|
||||||
{
|
|
||||||
await PutJsonAsync($"{Apiurl}/{settingKey}/{settingValue}", "");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,11 +38,6 @@ namespace Oqtane.Services
|
|||||||
.SelectMany(item => item.Containers).ToList();
|
.SelectMany(item => item.Containers).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InstallThemesAsync()
|
|
||||||
{
|
|
||||||
await GetJsonAsync<List<string>>($"{ApiUrl}/install");
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteThemeAsync(string themeName)
|
public async Task DeleteThemeAsync(string themeName)
|
||||||
{
|
{
|
||||||
await DeleteAsync($"{ApiUrl}/{themeName}");
|
await DeleteAsync($"{ApiUrl}/{themeName}");
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
@inherits ModuleActionsBase
|
@inherits ModuleActionsBase
|
||||||
@attribute [OqtaneIgnore]
|
@attribute [OqtaneIgnore]
|
||||||
|
|
||||||
@if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && PageState.Action == Constants.DefaultAction)
|
@if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList) && PageState.Action == Constants.DefaultAction)
|
||||||
{
|
{
|
||||||
<div class="app-moduleactions py-2 px-3">
|
<div class="app-moduleactions py-2 px-3">
|
||||||
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"></a>
|
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"></a>
|
||||||
|
@ -30,11 +30,11 @@ namespace Oqtane.Themes.Controls
|
|||||||
{
|
{
|
||||||
var actionList = new List<ActionViewModel>();
|
var actionList = new List<ActionViewModel>();
|
||||||
|
|
||||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList))
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel { Icon = Icons.Cog, Name = "Manage Settings", Action = async (u, m) => await Settings(u, m) });
|
actionList.Add(new ActionViewModel { Icon = Icons.Cog, Name = "Manage Settings", Action = async (u, m) => await Settings(u, m) });
|
||||||
|
|
||||||
if (UserSecurity.ContainsRole(ModuleState.Permissions, PermissionNames.View, RoleNames.Everyone))
|
if (UserSecurity.ContainsRole(ModuleState.PermissionList, PermissionNames.View, RoleNames.Everyone))
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel { Icon = Icons.CircleX, Name = "Unpublish Module", Action = async (s, m) => await Unpublish(s, m) });
|
actionList.Add(new ActionViewModel { Icon = Icons.CircleX, Name = "Unpublish Module", Action = async (s, m) => await Unpublish(s, m) });
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ namespace Oqtane.Themes.Controls
|
|||||||
}
|
}
|
||||||
actionList.Add(new ActionViewModel { Icon = Icons.Trash, Name = "Delete Module", Action = async (u, m) => await DeleteModule(u, m) });
|
actionList.Add(new ActionViewModel { Icon = Icons.Trash, Name = "Delete Module", Action = async (u, m) => await DeleteModule(u, m) });
|
||||||
|
|
||||||
if (ModuleState.ModuleDefinition != null && ModuleState.ModuleDefinition.ServerManagerType != "")
|
if (ModuleState.ModuleDefinition != null && ModuleState.ModuleDefinition.IsPortable)
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel { Name = "" });
|
actionList.Add(new ActionViewModel { Name = "" });
|
||||||
actionList.Add(new ActionViewModel { Icon = Icons.CloudUpload, Name = "Import Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Import") });
|
actionList.Add(new ActionViewModel { Icon = Icons.CloudUpload, Name = "Import Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Import") });
|
||||||
@ -93,7 +93,7 @@ namespace Oqtane.Themes.Controls
|
|||||||
|
|
||||||
protected async Task ModuleAction(ActionViewModel action)
|
protected async Task ModuleAction(ActionViewModel action)
|
||||||
{
|
{
|
||||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.Permissions))
|
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.PermissionList))
|
||||||
{
|
{
|
||||||
PageModule pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
|
PageModule pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
|
||||||
|
|
||||||
@ -136,36 +136,32 @@ namespace Oqtane.Themes.Controls
|
|||||||
|
|
||||||
private async Task<string> Publish(string url, PageModule pagemodule)
|
private async Task<string> Publish(string url, PageModule pagemodule)
|
||||||
{
|
{
|
||||||
var permissions = UserSecurity.GetPermissionStrings(pagemodule.Module.Permissions);
|
var permissions = pagemodule.Module.PermissionList;
|
||||||
foreach (var permissionstring in permissions)
|
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Everyone))
|
||||||
{
|
{
|
||||||
if (permissionstring.PermissionName == PermissionNames.View)
|
permissions.Add(new Permission(ModuleState.SiteId, EntityNames.Page, pagemodule.PageId, PermissionNames.View, RoleNames.Everyone, null, true));
|
||||||
|
}
|
||||||
|
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Registered))
|
||||||
{
|
{
|
||||||
List<string> ids = permissionstring.Permissions.Split(';').ToList();
|
permissions.Add(new Permission(ModuleState.SiteId, EntityNames.Page, pagemodule.PageId, PermissionNames.View, RoleNames.Registered, null, true));
|
||||||
if (!ids.Contains(RoleNames.Everyone)) ids.Add(RoleNames.Everyone);
|
|
||||||
if (!ids.Contains(RoleNames.Registered)) ids.Add(RoleNames.Registered);
|
|
||||||
permissionstring.Permissions = string.Join(";", ids.ToArray());
|
|
||||||
}
|
}
|
||||||
}
|
pagemodule.Module.PermissionList = permissions;
|
||||||
pagemodule.Module.Permissions = UserSecurity.SetPermissionStrings(permissions);
|
|
||||||
await ModuleService.UpdateModuleAsync(pagemodule.Module);
|
await ModuleService.UpdateModuleAsync(pagemodule.Module);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> Unpublish(string url, PageModule pagemodule)
|
private async Task<string> Unpublish(string url, PageModule pagemodule)
|
||||||
{
|
{
|
||||||
var permissions = UserSecurity.GetPermissionStrings(pagemodule.Module.Permissions);
|
var permissions = pagemodule.Module.PermissionList;
|
||||||
foreach (var permissionstring in permissions)
|
if (permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Everyone))
|
||||||
{
|
{
|
||||||
if (permissionstring.PermissionName == PermissionNames.View)
|
permissions.Remove(permissions.First(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Everyone));
|
||||||
|
}
|
||||||
|
if (permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Registered))
|
||||||
{
|
{
|
||||||
List<string> ids = permissionstring.Permissions.Split(';').ToList();
|
permissions.Remove(permissions.First(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Registered));
|
||||||
ids.Remove(RoleNames.Everyone);
|
|
||||||
ids.Remove(RoleNames.Registered);
|
|
||||||
permissionstring.Permissions = string.Join(";", ids.ToArray());
|
|
||||||
}
|
}
|
||||||
}
|
pagemodule.Module.PermissionList = permissions;
|
||||||
pagemodule.Module.Permissions = UserSecurity.SetPermissionStrings(permissions);
|
|
||||||
await ModuleService.UpdateModuleAsync(pagemodule.Module);
|
await ModuleService.UpdateModuleAsync(pagemodule.Module);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (_canViewAdminDashboard || UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
@if (_canViewAdminDashboard || UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn @ButtonClass" data-bs-toggle="offcanvas" data-bs-target="#offcanvasControlPanel" aria-controls="offcanvasControlPanel">
|
<button type="button" class="btn @ButtonClass" data-bs-toggle="offcanvas" data-bs-target="#offcanvasControlPanel" aria-controls="offcanvasControlPanel">
|
||||||
<span class="oi oi-cog"></span>
|
<span class="oi oi-cog"></span>
|
||||||
@ -71,7 +71,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row d-flex">
|
<div class="row d-flex">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@if (UserSecurity.ContainsRole(PageState.Page.Permissions, PermissionNames.View, RoleNames.Everyone))
|
@if (UserSecurity.ContainsRole(PageState.Page.PermissionList, PermissionNames.View, RoleNames.Everyone))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-secondary col-12" @onclick=@(async () => Publish("unpublish"))>@Localizer["Page.Unpublish"]</button>
|
<button type="button" class="btn btn-secondary col-12" @onclick=@(async () => Publish("unpublish"))>@Localizer["Page.Unpublish"]</button>
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList))
|
||||||
{
|
{
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col text-center">
|
<div class="col text-center">
|
||||||
@ -144,7 +144,7 @@
|
|||||||
}
|
}
|
||||||
@foreach (var moduledefinition in _moduleDefinitions)
|
@foreach (var moduledefinition in _moduleDefinitions)
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize, moduledefinition.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize, moduledefinition.PermissionList))
|
||||||
{
|
{
|
||||||
if (moduledefinition.Runtimes == "" || moduledefinition.Runtimes.Contains(PageState.Runtime.ToString()))
|
if (moduledefinition.Runtimes == "" || moduledefinition.Runtimes.Contains(PageState.Runtime.ToString()))
|
||||||
{
|
{
|
||||||
@ -294,14 +294,14 @@
|
|||||||
{
|
{
|
||||||
_canViewAdminDashboard = CanViewAdminDashboard();
|
_canViewAdminDashboard = CanViewAdminDashboard();
|
||||||
_showEditMode = false;
|
_showEditMode = false;
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList))
|
||||||
{
|
{
|
||||||
_showEditMode = true;
|
_showEditMode = true;
|
||||||
_pages?.Clear();
|
_pages?.Clear();
|
||||||
|
|
||||||
foreach (Page p in PageState.Pages)
|
foreach (Page p in PageState.Pages)
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
{
|
{
|
||||||
_pages.Add(p);
|
_pages.Add(p);
|
||||||
}
|
}
|
||||||
@ -319,7 +319,7 @@
|
|||||||
{
|
{
|
||||||
foreach (var module in PageState.Modules.Where(item => item.PageId == PageState.Page.PageId))
|
foreach (var module in PageState.Modules.Where(item => item.PageId == PageState.Page.PageId))
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, module.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, module.PermissionList))
|
||||||
{
|
{
|
||||||
_showEditMode = true;
|
_showEditMode = true;
|
||||||
break;
|
break;
|
||||||
@ -335,7 +335,7 @@
|
|||||||
{
|
{
|
||||||
foreach (var page in PageState.Pages.Where(item => item.ParentId == admin?.PageId))
|
foreach (var page in PageState.Pages.Where(item => item.ParentId == admin?.PageId))
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, page.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, page.PermissionList))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -371,7 +371,7 @@
|
|||||||
{
|
{
|
||||||
_modules = PageState.Modules
|
_modules = PageState.Modules
|
||||||
.Where(module => module.PageId == int.Parse(PageId) &&
|
.Where(module => module.PageId == int.Parse(PageId) &&
|
||||||
UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.PermissionList))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
ModuleId = "-";
|
ModuleId = "-";
|
||||||
@ -380,7 +380,7 @@
|
|||||||
|
|
||||||
private async Task AddModule()
|
private async Task AddModule()
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList))
|
||||||
{
|
{
|
||||||
if ((ModuleType == "new" && ModuleDefinitionName != "-") || (ModuleType != "new" && ModuleId != "-"))
|
if ((ModuleType == "new" && ModuleDefinitionName != "-") || (ModuleType != "new" && ModuleId != "-"))
|
||||||
{
|
{
|
||||||
@ -392,18 +392,20 @@
|
|||||||
module.ModuleDefinitionName = ModuleDefinitionName;
|
module.ModuleDefinitionName = ModuleDefinitionName;
|
||||||
module.AllPages = false;
|
module.AllPages = false;
|
||||||
|
|
||||||
List<PermissionString> permissions = UserSecurity.GetPermissionStrings(PageState.Page.Permissions);
|
var permissions = new List<Permission>();
|
||||||
if (Visibility == "view")
|
if (Visibility == "view")
|
||||||
{
|
{
|
||||||
// set module view permissions to page view permissions
|
// set module view permissions to page view permissions
|
||||||
permissions.Find(p => p.PermissionName == PermissionNames.View).Permissions = permissions.Find(p => p.PermissionName == PermissionNames.View).Permissions;
|
permissions = SetPermissions(permissions, module.SiteId, PermissionNames.View, PermissionNames.View);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// set module view permissions to page edit permissions
|
// set module view permissions to page edit permissions
|
||||||
permissions.Find(p => p.PermissionName == PermissionNames.View).Permissions = permissions.Find(p => p.PermissionName == PermissionNames.Edit).Permissions;
|
permissions = SetPermissions(permissions, module.SiteId, PermissionNames.View, PermissionNames.Edit);
|
||||||
}
|
}
|
||||||
module.Permissions = UserSecurity.SetPermissionStrings(permissions);
|
// set module edit permissions to page edit permissions
|
||||||
|
permissions = SetPermissions(permissions, module.SiteId, PermissionNames.Edit, PermissionNames.Edit);
|
||||||
|
module.PermissionList = permissions;
|
||||||
|
|
||||||
module = await ModuleService.AddModuleAsync(module);
|
module = await ModuleService.AddModuleAsync(module);
|
||||||
ModuleId = module.ModuleId.ToString();
|
ModuleId = module.ModuleId.ToString();
|
||||||
@ -454,6 +456,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Permission> SetPermissions(List<Permission> permissions, int siteId, string modulePermission, string pagePermission)
|
||||||
|
{
|
||||||
|
foreach (var permission in PageState.Page.PermissionList.Where(item => item.PermissionName == pagePermission))
|
||||||
|
{
|
||||||
|
permissions.Add(new Permission { SiteId = siteId, EntityName = EntityNames.Module, PermissionName = modulePermission, RoleId = permission.RoleId, UserId = permission.UserId, IsAuthorized = permission.IsAuthorized });
|
||||||
|
}
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ToggleEditMode(bool EditMode)
|
private async Task ToggleEditMode(bool EditMode)
|
||||||
{
|
{
|
||||||
if (_showEditMode)
|
if (_showEditMode)
|
||||||
@ -467,7 +478,7 @@
|
|||||||
PageState.EditMode = true;
|
PageState.EditMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "1" : "0")));
|
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "true" : "false")));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -475,7 +486,7 @@
|
|||||||
{
|
{
|
||||||
await PageService.AddPageAsync(PageState.Page.PageId, PageState.User.UserId);
|
await PageService.AddPageAsync(PageState.Page.PageId, PageState.User.UserId);
|
||||||
PageState.EditMode = true;
|
PageState.EditMode = true;
|
||||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "1" : "0")));
|
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "true" : "false")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -523,34 +534,19 @@
|
|||||||
|
|
||||||
private async void Publish(string action)
|
private async void Publish(string action)
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList))
|
||||||
{
|
{
|
||||||
List<PermissionString> permissions;
|
var permissions = PageState.Page.PermissionList;
|
||||||
|
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Everyone))
|
||||||
// publish/unpublish page
|
|
||||||
var page = PageState.Page;
|
|
||||||
permissions = UserSecurity.GetPermissionStrings(page.Permissions);
|
|
||||||
foreach (var permissionstring in permissions)
|
|
||||||
{
|
{
|
||||||
if (permissionstring.PermissionName == PermissionNames.View)
|
permissions.Add(new Permission(PageState.Site.SiteId, EntityNames.Page, PageState.Page.PageId, PermissionNames.View, RoleNames.Everyone, null, true));
|
||||||
{
|
|
||||||
List<string> ids = permissionstring.Permissions.Split(';').ToList();
|
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case "publish":
|
|
||||||
if (!ids.Contains(RoleNames.Everyone)) ids.Add(RoleNames.Everyone);
|
|
||||||
if (!ids.Contains(RoleNames.Registered)) ids.Add(RoleNames.Registered);
|
|
||||||
break;
|
|
||||||
case "unpublish":
|
|
||||||
ids.Remove(RoleNames.Everyone);
|
|
||||||
ids.Remove(RoleNames.Registered);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
permissionstring.Permissions = string.Join(";", ids.ToArray());
|
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Registered))
|
||||||
|
{
|
||||||
|
permissions.Add(new Permission(PageState.Site.SiteId, EntityNames.Page, PageState.Page.PageId, PermissionNames.View, RoleNames.Registered, null, true));
|
||||||
}
|
}
|
||||||
}
|
PageState.Page.PermissionList = permissions;
|
||||||
page.Permissions = UserSecurity.SetPermissionStrings(permissions);
|
await PageService.UpdatePageAsync(PageState.Page);
|
||||||
await PageService.UpdatePageAsync(page);
|
|
||||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true));
|
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
using Oqtane.Enums;
|
using Oqtane.Enums;
|
||||||
|
using Oqtane.Models;
|
||||||
using Oqtane.Providers;
|
using Oqtane.Providers;
|
||||||
using Oqtane.Security;
|
using Oqtane.Security;
|
||||||
using Oqtane.Services;
|
using Oqtane.Services;
|
||||||
@ -22,21 +24,19 @@ namespace Oqtane.Themes.Controls
|
|||||||
|
|
||||||
protected void LoginUser()
|
protected void LoginUser()
|
||||||
{
|
{
|
||||||
var returnurl = PageState.Alias.Path;
|
Route route = new Route(PageState.Uri.AbsoluteUri, PageState.Alias.Path);
|
||||||
if (PageState.Page.Path != "/")
|
NavigationManager.NavigateTo(NavigateUrl("login", "?returnurl=" + WebUtility.UrlEncode(route.PathAndQuery)));
|
||||||
{
|
|
||||||
returnurl += "/" + PageState.Page.Path;
|
|
||||||
}
|
|
||||||
NavigationManager.NavigateTo(NavigateUrl("login", "?returnurl=" + returnurl));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task LogoutUser()
|
protected async Task LogoutUser()
|
||||||
{
|
{
|
||||||
await LoggingService.Log(PageState.Alias, PageState.Page.PageId, null, PageState.User?.UserId, GetType().AssemblyQualifiedName, "Logout", LogFunction.Security, LogLevel.Information, null, "User Logout For Username {Username}", PageState.User?.Username);
|
await LoggingService.Log(PageState.Alias, PageState.Page.PageId, null, PageState.User?.UserId, GetType().AssemblyQualifiedName, "Logout", LogFunction.Security, LogLevel.Information, null, "User Logout For Username {Username}", PageState.User?.Username);
|
||||||
|
|
||||||
// check if anonymous user can access page
|
Route route = new Route(PageState.Uri.AbsoluteUri, PageState.Alias.Path);
|
||||||
var url = PageState.Alias.Path + "/" + PageState.Page.Path;
|
var url = route.PathAndQuery;
|
||||||
if (!UserSecurity.IsAuthorized(null, PermissionNames.View, PageState.Page.Permissions))
|
|
||||||
|
// verify if anonymous users can access page
|
||||||
|
if (!UserSecurity.IsAuthorized(null, PermissionNames.View, PageState.Page.PermissionList))
|
||||||
{
|
{
|
||||||
url = PageState.Alias.Path;
|
url = PageState.Alias.Path;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ namespace Oqtane.Themes.Controls
|
|||||||
var securityLevel = int.MaxValue;
|
var securityLevel = int.MaxValue;
|
||||||
foreach (Page p in PageState.Pages.Where(item => item.IsNavigation))
|
foreach (Page p in PageState.Pages.Where(item => item.IsNavigation))
|
||||||
{
|
{
|
||||||
if (p.Level <= securityLevel && UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
if (p.Level <= securityLevel && UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
{
|
{
|
||||||
securityLevel = int.MaxValue;
|
securityLevel = int.MaxValue;
|
||||||
yield return p;
|
yield return p;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
<div class="app-menu navbar-expand-md">
|
<div class="app-menu navbar-expand-md">
|
||||||
<div class="collapse navbar-collapse" id="Menu">
|
<div class="collapse navbar-collapse navbar-nav-scroll" id="Menu">
|
||||||
<MenuItemsHorizontal ParentPage="null" Pages="MenuPages" />
|
<MenuItemsHorizontal ParentPage="null" Pages="MenuPages" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
container = (!string.IsNullOrEmpty(PageState.Site.AdminContainerType)) ? PageState.Site.AdminContainerType : Constants.DefaultAdminContainer;
|
container = (!string.IsNullOrEmpty(PageState.Site.AdminContainerType)) ? PageState.Site.AdminContainerType : Constants.DefaultAdminContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && PageState.Action == Constants.DefaultAction)
|
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList) && PageState.Action == Constants.DefaultAction)
|
||||||
{
|
{
|
||||||
_useadminborder = true;
|
_useadminborder = true;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ else
|
|||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && PageState.Action == Constants.DefaultAction)
|
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList) && PageState.Action == Constants.DefaultAction)
|
||||||
{
|
{
|
||||||
_useadminborder = true;
|
_useadminborder = true;
|
||||||
_panetitle = "<div class=\"app-pane-admin-title\">" + Name + " Pane</div>";
|
_panetitle = "<div class=\"app-pane-admin-title\">" + Name + " Pane</div>";
|
||||||
@ -58,7 +58,11 @@ else
|
|||||||
}
|
}
|
||||||
if (Name.ToLower() == pane.ToLower())
|
if (Name.ToLower() == pane.ToLower())
|
||||||
{
|
{
|
||||||
Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
Module module = PageState.Modules.FirstOrDefault(item => item.PageId == PageState.Page.PageId && item.ModuleId == PageState.ModuleId);
|
||||||
|
if (module == null)
|
||||||
|
{
|
||||||
|
module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
||||||
|
}
|
||||||
if (module != null)
|
if (module != null)
|
||||||
{
|
{
|
||||||
var moduleType = Type.GetType(module.ModuleType);
|
var moduleType = Type.GetType(module.ModuleType);
|
||||||
@ -67,7 +71,7 @@ else
|
|||||||
bool authorized = false;
|
bool authorized = false;
|
||||||
if (Constants.DefaultModuleActions.Contains(PageState.Action))
|
if (Constants.DefaultModuleActions.Contains(PageState.Action))
|
||||||
{
|
{
|
||||||
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions);
|
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -77,10 +81,10 @@ else
|
|||||||
authorized = true;
|
authorized = true;
|
||||||
break;
|
break;
|
||||||
case SecurityAccessLevel.View:
|
case SecurityAccessLevel.View:
|
||||||
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions);
|
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.PermissionList);
|
||||||
break;
|
break;
|
||||||
case SecurityAccessLevel.Edit:
|
case SecurityAccessLevel.Edit:
|
||||||
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, module.Permissions);
|
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, module.PermissionList);
|
||||||
break;
|
break;
|
||||||
case SecurityAccessLevel.Admin:
|
case SecurityAccessLevel.Admin:
|
||||||
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin);
|
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin);
|
||||||
@ -107,11 +111,15 @@ else
|
|||||||
{
|
{
|
||||||
if (PageState.ModuleId != -1)
|
if (PageState.ModuleId != -1)
|
||||||
{
|
{
|
||||||
Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
Module module = PageState.Modules.FirstOrDefault(item => item.PageId == PageState.Page.PageId && item.ModuleId == PageState.ModuleId);
|
||||||
|
if (module == null)
|
||||||
|
{
|
||||||
|
module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
||||||
|
}
|
||||||
if (module != null && module.Pane.ToLower() == Name.ToLower())
|
if (module != null && module.Pane.ToLower() == Name.ToLower())
|
||||||
{
|
{
|
||||||
// check if user is authorized to view module
|
// check if user is authorized to view module
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.PermissionList))
|
||||||
{
|
{
|
||||||
CreateComponent(builder, module);
|
CreateComponent(builder, module);
|
||||||
}
|
}
|
||||||
@ -119,10 +127,10 @@ else
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (Module module in PageState.Modules.Where(item => item.PageId == PageState.Page.PageId && item.Pane.ToLower() == Name.ToLower()).OrderBy(x => x.Order).ToArray())
|
foreach (Module module in PageState.Modules.Where(item => item.PageId == PageState.Page.PageId && item.Pane.ToLower() == Name.ToLower()))
|
||||||
{
|
{
|
||||||
// check if user is authorized to view module
|
// check if user is authorized to view module
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.PermissionList))
|
||||||
{
|
{
|
||||||
CreateComponent(builder, module);
|
CreateComponent(builder, module);
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,10 @@
|
|||||||
editmode = PageState.EditMode;
|
editmode = PageState.EditMode;
|
||||||
lastsyncdate = PageState.LastSyncDate;
|
lastsyncdate = PageState.LastSyncDate;
|
||||||
}
|
}
|
||||||
|
if (PageState?.Page.Path != route.PagePath)
|
||||||
|
{
|
||||||
|
editmode = false; // reset edit mode when navigating to different page
|
||||||
|
}
|
||||||
|
|
||||||
// get user
|
// get user
|
||||||
if (PageState == null || refresh || PageState.Alias.SiteId != SiteState.Alias.SiteId)
|
if (PageState == null || refresh || PageState.Alias.SiteId != SiteState.Alias.SiteId)
|
||||||
@ -181,7 +185,6 @@
|
|||||||
if (PageState == null || refresh || PageState.Page.Path != route.PagePath)
|
if (PageState == null || refresh || PageState.Page.Path != route.PagePath)
|
||||||
{
|
{
|
||||||
page = site.Pages.FirstOrDefault(item => item.Path.Equals(route.PagePath, StringComparison.OrdinalIgnoreCase));
|
page = site.Pages.FirstOrDefault(item => item.Path.Equals(route.PagePath, StringComparison.OrdinalIgnoreCase));
|
||||||
editmode = false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -204,7 +207,7 @@
|
|||||||
if (page != null)
|
if (page != null)
|
||||||
{
|
{
|
||||||
// check if user is authorized to view page
|
// check if user is authorized to view page
|
||||||
if (UserSecurity.IsAuthorized(user, PermissionNames.View, page.Permissions))
|
if (UserSecurity.IsAuthorized(user, PermissionNames.View, page.PermissionList))
|
||||||
{
|
{
|
||||||
// load additional metadata for current page
|
// load additional metadata for current page
|
||||||
page = await ProcessPage(page, site, user);
|
page = await ProcessPage(page, site, user);
|
||||||
@ -250,7 +253,7 @@
|
|||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
// redirect to login page if user not logged in as they may need to be authenticated
|
// redirect to login page if user not logged in as they may need to be authenticated
|
||||||
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "login", "?returnurl=" + route.AbsolutePath));
|
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "login", "?returnurl=" + WebUtility.UrlEncode(route.PathAndQuery)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -299,22 +302,28 @@
|
|||||||
{
|
{
|
||||||
query = query.Substring(1); // ignore "?"
|
query = query.Substring(1); // ignore "?"
|
||||||
}
|
}
|
||||||
foreach (string kvp in query.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries))
|
foreach (string kvp in query.Split('&', StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
if (kvp != "")
|
if (kvp != "")
|
||||||
{
|
{
|
||||||
if (kvp.Contains("="))
|
if (kvp.Contains("="))
|
||||||
{
|
{
|
||||||
string[] pair = kvp.Split('=');
|
string[] pair = kvp.Split('=');
|
||||||
|
if (!querystring.ContainsKey(pair[0]))
|
||||||
|
{
|
||||||
querystring.Add(pair[0], pair[1]);
|
querystring.Add(pair[0], pair[1]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (!querystring.ContainsKey(kvp))
|
||||||
{
|
{
|
||||||
querystring.Add(kvp, "true"); // default parameter when no value is provided
|
querystring.Add(kvp, "true"); // default parameter when no value is provided
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return querystring;
|
return querystring;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +367,7 @@
|
|||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(panes))
|
if (!string.IsNullOrEmpty(panes))
|
||||||
{
|
{
|
||||||
page.Panes = panes.Replace(";", ",").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
page.Panes = panes.Replace(";", ",").Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||||
if (!page.Panes.Contains(PaneNames.Default) && !page.Panes.Contains(PaneNames.Admin))
|
if (!page.Panes.Contains(PaneNames.Default) && !page.Panes.Contains(PaneNames.Admin))
|
||||||
{
|
{
|
||||||
_error = "The Current Theme Does Not Contain A Default Or Admin Pane";
|
_error = "The Current Theme Does Not Contain A Default Or Admin Pane";
|
||||||
@ -407,7 +416,7 @@
|
|||||||
// check if the module defines custom action routes
|
// check if the module defines custom action routes
|
||||||
if (module.ModuleDefinition.ControlTypeRoutes != "")
|
if (module.ModuleDefinition.ControlTypeRoutes != "")
|
||||||
{
|
{
|
||||||
foreach (string route in module.ModuleDefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
foreach (string route in module.ModuleDefinition.ControlTypeRoutes.Split(';', StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
if (route.StartsWith(action + "="))
|
if (route.StartsWith(action + "="))
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>3.3.0</Version>
|
<Version>3.4.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Database.MySQL</id>
|
<id>Oqtane.Database.MySQL</id>
|
||||||
<version>3.3.0</version>
|
<version>3.4.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane MySQL Provider</title>
|
<title>Oqtane MySQL Provider</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>3.3.0</Version>
|
<Version>3.4.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Database.PostgreSQL</id>
|
<id>Oqtane.Database.PostgreSQL</id>
|
||||||
<version>3.3.0</version>
|
<version>3.4.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane PostgreSQL Provider</title>
|
<title>Oqtane PostgreSQL Provider</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>3.3.0</Version>
|
<Version>3.4.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Database.SqlServer</id>
|
<id>Oqtane.Database.SqlServer</id>
|
||||||
<version>3.3.0</version>
|
<version>3.4.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane SQL Server Provider</title>
|
<title>Oqtane SQL Server Provider</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>3.3.0</Version>
|
<Version>3.4.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Database.Sqlite</id>
|
<id>Oqtane.Database.Sqlite</id>
|
||||||
<version>3.3.0</version>
|
<version>3.4.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane SQLite Provider</title>
|
<title>Oqtane SQLite Provider</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -212,6 +212,8 @@ public static class MauiProgram
|
|||||||
private static void RegisterModuleServices(Assembly assembly, IServiceCollection services)
|
private static void RegisterModuleServices(Assembly assembly, IServiceCollection services)
|
||||||
{
|
{
|
||||||
// dynamically register module scoped services
|
// dynamically register module scoped services
|
||||||
|
try
|
||||||
|
{
|
||||||
var implementationTypes = assembly.GetInterfaces<IService>();
|
var implementationTypes = assembly.GetInterfaces<IService>();
|
||||||
foreach (var implementationType in implementationTypes)
|
foreach (var implementationType in implementationTypes)
|
||||||
{
|
{
|
||||||
@ -222,8 +224,15 @@ public static class MauiProgram
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// could not interrogate assembly - likely missing dependencies
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void RegisterClientStartups(Assembly assembly, IServiceCollection services)
|
private static void RegisterClientStartups(Assembly assembly, IServiceCollection services)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var startUps = assembly.GetInstances<IClientStartup>();
|
var startUps = assembly.GetInstances<IClientStartup>();
|
||||||
foreach (var startup in startUps)
|
foreach (var startup in startUps)
|
||||||
@ -231,4 +240,9 @@ public static class MauiProgram
|
|||||||
startup.ConfigureServices(services);
|
startup.ConfigureServices(services);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// could not interrogate assembly - likely missing dependencies
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks>
|
|
||||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net6.0-windows10.0.19041.0</TargetFrameworks>
|
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net6.0-windows10.0.19041.0</TargetFrameworks>
|
||||||
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
|
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
|
||||||
|
<!-- <TargetFrameworks>net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks> -->
|
||||||
<!-- <TargetFrameworks>$(TargetFrameworks);net6.0-tizen</TargetFrameworks> -->
|
<!-- <TargetFrameworks>$(TargetFrameworks);net6.0-tizen</TargetFrameworks> -->
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<Version>3.3.0</Version>
|
<Version>3.4.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -14,7 +14,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<RootNamespace>Oqtane.Maui</RootNamespace>
|
<RootNamespace>Oqtane.Maui</RootNamespace>
|
||||||
@ -31,7 +31,7 @@
|
|||||||
<ApplicationIdGuid>0E29FC31-1B83-48ED-B6E0-9F3C67B775D4</ApplicationIdGuid>
|
<ApplicationIdGuid>0E29FC31-1B83-48ED-B6E0-9F3C67B775D4</ApplicationIdGuid>
|
||||||
|
|
||||||
<!-- Versions -->
|
<!-- Versions -->
|
||||||
<ApplicationDisplayVersion>3.3.0</ApplicationDisplayVersion>
|
<ApplicationDisplayVersion>3.4.3</ApplicationDisplayVersion>
|
||||||
<ApplicationVersion>1</ApplicationVersion>
|
<ApplicationVersion>1</ApplicationVersion>
|
||||||
|
|
||||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
|
||||||
@ -71,8 +71,8 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="6.0.3" />
|
<PackageReference Include="Microsoft.Extensions.Localization" Version="6.0.3" />
|
||||||
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
|
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
|
||||||
<PackageReference Include="Oqtane.Client" Version="3.3.0" />
|
<PackageReference Include="Oqtane.Client" Version="3.4.3" />
|
||||||
<PackageReference Include="Oqtane.Shared" Version="3.3.0" />
|
<PackageReference Include="Oqtane.Shared" Version="3.4.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Client</id>
|
<id>Oqtane.Client</id>
|
||||||
<version>3.3.0</version>
|
<version>3.4.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Framework</id>
|
<id>Oqtane.Framework</id>
|
||||||
<version>3.3.0</version>
|
<version>3.4.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -11,8 +11,8 @@
|
|||||||
<copyright>.NET Foundation</copyright>
|
<copyright>.NET Foundation</copyright>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v3.3.0/Oqtane.Framework.3.2.1.Upgrade.zip</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v3.4.3/Oqtane.Framework.3.4.3.Upgrade.zip</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane framework</tags>
|
<tags>oqtane framework</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Server</id>
|
<id>Oqtane.Server</id>
|
||||||
<version>3.3.0</version>
|
<version>3.4.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Shared</id>
|
<id>Oqtane.Shared</id>
|
||||||
<version>3.3.0</version>
|
<version>3.4.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Updater</id>
|
<id>Oqtane.Updater</id>
|
||||||
<version>3.3.0</version>
|
<version>3.4.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.3.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -1 +1 @@
|
|||||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.3.0.Install.zip" -Force
|
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.4.3.Install.zip" -Force
|
@ -1 +1 @@
|
|||||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.3.0.Upgrade.zip" -Force
|
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.4.3.Upgrade.zip" -Force
|
@ -20,7 +20,6 @@ using SixLabors.ImageSharp;
|
|||||||
using SixLabors.ImageSharp.Processing;
|
using SixLabors.ImageSharp.Processing;
|
||||||
using SixLabors.ImageSharp.Formats.Png;
|
using SixLabors.ImageSharp.Formats.Png;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using Oqtane.Migrations.Tenant;
|
|
||||||
|
|
||||||
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
||||||
|
|
||||||
@ -57,7 +56,7 @@ namespace Oqtane.Controllers
|
|||||||
if (int.TryParse(folder, out folderid))
|
if (int.TryParse(folder, out folderid))
|
||||||
{
|
{
|
||||||
Folder Folder = _folders.GetFolder(folderid);
|
Folder Folder = _folders.GetFolder(folderid);
|
||||||
if (Folder != null && Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Browse, Folder.Permissions))
|
if (Folder != null && Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Browse, Folder.PermissionList))
|
||||||
{
|
{
|
||||||
files = _files.GetFiles(folderid).ToList();
|
files = _files.GetFiles(folderid).ToList();
|
||||||
}
|
}
|
||||||
@ -99,7 +98,7 @@ namespace Oqtane.Controllers
|
|||||||
List<Models.File> files;
|
List<Models.File> files;
|
||||||
|
|
||||||
Folder folder = _folders.GetFolder(siteId, WebUtility.UrlDecode(path));
|
Folder folder = _folders.GetFolder(siteId, WebUtility.UrlDecode(path));
|
||||||
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.Permissions))
|
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.PermissionList))
|
||||||
{
|
{
|
||||||
files = _files.GetFiles(folder.FolderId).ToList();
|
files = _files.GetFiles(folder.FolderId).ToList();
|
||||||
}
|
}
|
||||||
@ -118,7 +117,7 @@ namespace Oqtane.Controllers
|
|||||||
public Models.File Get(int id)
|
public Models.File Get(int id)
|
||||||
{
|
{
|
||||||
Models.File file = _files.GetFile(id);
|
Models.File file = _files.GetFile(id);
|
||||||
if (file != null && file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
|
if (file != null && file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.PermissionList))
|
||||||
{
|
{
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
@ -142,7 +141,7 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
if (File.Name != file.Name || File.FolderId != file.FolderId)
|
if (File.Name != file.Name || File.FolderId != file.FolderId)
|
||||||
{
|
{
|
||||||
file.Folder = _folders.GetFolder(file.FolderId);
|
file.Folder = _folders.GetFolder(file.FolderId, false);
|
||||||
string folderpath = _folders.GetFolderPath(file.Folder);
|
string folderpath = _folders.GetFolderPath(file.Folder);
|
||||||
if (!Directory.Exists(folderpath))
|
if (!Directory.Exists(folderpath))
|
||||||
{
|
{
|
||||||
@ -151,7 +150,7 @@ namespace Oqtane.Controllers
|
|||||||
System.IO.File.Move(_files.GetFilePath(File), Path.Combine(folderpath, file.Name));
|
System.IO.File.Move(_files.GetFilePath(File), Path.Combine(folderpath, file.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
var newfile = CreateFile(file.Name, file.Folder.FolderId, _files.GetFilePath(file));
|
var newfile = CreateFile(File.Name, file.Folder.FolderId, _files.GetFilePath(file));
|
||||||
if (newfile != null)
|
if (newfile != null)
|
||||||
{
|
{
|
||||||
file.Extension = newfile.Extension;
|
file.Extension = newfile.Extension;
|
||||||
@ -216,7 +215,7 @@ namespace Oqtane.Controllers
|
|||||||
folder = _folders.GetFolder(FolderId);
|
folder = _folders.GetFolder(FolderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Edit, folder.Permissions))
|
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Edit, folder.PermissionList))
|
||||||
{
|
{
|
||||||
string folderPath = _folders.GetFolderPath(folder);
|
string folderPath = _folders.GetFolderPath(folder);
|
||||||
CreateDirectory(folderPath);
|
CreateDirectory(folderPath);
|
||||||
@ -311,7 +310,7 @@ namespace Oqtane.Controllers
|
|||||||
if (int.TryParse(folder, out FolderId))
|
if (int.TryParse(folder, out FolderId))
|
||||||
{
|
{
|
||||||
Folder Folder = _folders.GetFolder(FolderId);
|
Folder Folder = _folders.GetFolder(FolderId);
|
||||||
if (Folder != null && Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Edit, Folder.Permissions))
|
if (Folder != null && Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Edit, Folder.PermissionList))
|
||||||
{
|
{
|
||||||
folderPath = _folders.GetFolderPath(Folder);
|
folderPath = _folders.GetFolderPath(Folder);
|
||||||
}
|
}
|
||||||
@ -498,7 +497,7 @@ namespace Oqtane.Controllers
|
|||||||
private IActionResult Download(int id, bool asAttachment)
|
private IActionResult Download(int id, bool asAttachment)
|
||||||
{
|
{
|
||||||
var file = _files.GetFile(id);
|
var file = _files.GetFile(id);
|
||||||
if (file != null && file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
|
if (file != null && file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.PermissionList))
|
||||||
{
|
{
|
||||||
var filepath = _files.GetFilePath(file);
|
var filepath = _files.GetFilePath(file);
|
||||||
if (System.IO.File.Exists(filepath))
|
if (System.IO.File.Exists(filepath))
|
||||||
@ -533,7 +532,7 @@ namespace Oqtane.Controllers
|
|||||||
public IActionResult GetImage(int id, int width, int height, string mode, string position, string background, string rotate, string recreate)
|
public IActionResult GetImage(int id, int width, int height, string mode, string position, string background, string rotate, string recreate)
|
||||||
{
|
{
|
||||||
var file = _files.GetFile(id);
|
var file = _files.GetFile(id);
|
||||||
if (file != null && file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
|
if (file != null && file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.PermissionList))
|
||||||
{
|
{
|
||||||
if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower()))
|
if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower()))
|
||||||
{
|
{
|
||||||
@ -551,7 +550,7 @@ namespace Oqtane.Controllers
|
|||||||
string imagepath = filepath.Replace(Path.GetExtension(filepath), "." + width.ToString() + "x" + height.ToString() + ".png");
|
string imagepath = filepath.Replace(Path.GetExtension(filepath), "." + width.ToString() + "x" + height.ToString() + ".png");
|
||||||
if (!System.IO.File.Exists(imagepath) || bool.Parse(recreate))
|
if (!System.IO.File.Exists(imagepath) || bool.Parse(recreate))
|
||||||
{
|
{
|
||||||
if ((_userPermissions.IsAuthorized(User, PermissionNames.Edit, file.Folder.Permissions) ||
|
if ((_userPermissions.IsAuthorized(User, PermissionNames.Edit, file.Folder.PermissionList) ||
|
||||||
!string.IsNullOrEmpty(file.Folder.ImageSizes) && file.Folder.ImageSizes.ToLower().Split(",").Contains(width.ToString() + "x" + height.ToString())))
|
!string.IsNullOrEmpty(file.Folder.ImageSizes) && file.Folder.ImageSizes.ToLower().Split(",").Contains(width.ToString() + "x" + height.ToString())))
|
||||||
{
|
{
|
||||||
imagepath = CreateImage(filepath, width, height, mode, position, background, rotate, imagepath);
|
imagepath = CreateImage(filepath, width, height, mode, position, background, rotate, imagepath);
|
||||||
@ -659,10 +658,10 @@ namespace Oqtane.Controllers
|
|||||||
var file = _files.GetFile(folderid, filename);
|
var file = _files.GetFile(folderid, filename);
|
||||||
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
var folder = _folders.GetFolder(folderid);
|
var folder = _folders.GetFolder(folderid, false);
|
||||||
if (folder.Capacity != 0)
|
if (folder.Capacity != 0)
|
||||||
{
|
{
|
||||||
foreach (var f in _files.GetFiles(folderid))
|
foreach (var f in _files.GetFiles(folderid, false))
|
||||||
{
|
{
|
||||||
size += f.Size;
|
size += f.Size;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
foreach (Folder folder in _folders.GetFolders(SiteId))
|
foreach (Folder folder in _folders.GetFolders(SiteId))
|
||||||
{
|
{
|
||||||
if (_userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.Permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.PermissionList))
|
||||||
{
|
{
|
||||||
folders.Add(folder);
|
folders.Add(folder);
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ namespace Oqtane.Controllers
|
|||||||
public Folder Get(int id)
|
public Folder Get(int id)
|
||||||
{
|
{
|
||||||
Folder folder = _folders.GetFolder(id);
|
Folder folder = _folders.GetFolder(id);
|
||||||
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.Permissions))
|
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.PermissionList))
|
||||||
{
|
{
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ namespace Oqtane.Controllers
|
|||||||
folderPath += "/";
|
folderPath += "/";
|
||||||
}
|
}
|
||||||
Folder folder = _folders.GetFolder(siteId, folderPath);
|
Folder folder = _folders.GetFolder(siteId, folderPath);
|
||||||
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.Permissions))
|
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.PermissionList))
|
||||||
{
|
{
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
@ -104,16 +104,16 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
if (ModelState.IsValid && folder.SiteId == _alias.SiteId)
|
if (ModelState.IsValid && folder.SiteId == _alias.SiteId)
|
||||||
{
|
{
|
||||||
string permissions;
|
List<Permission> permissions;
|
||||||
if (folder.ParentId != null)
|
if (folder.ParentId != null)
|
||||||
{
|
{
|
||||||
permissions = _folders.GetFolder(folder.ParentId.Value).Permissions;
|
permissions = _folders.GetFolder(folder.ParentId.Value).PermissionList;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
permissions = new List<Permission> {
|
permissions = new List<Permission> {
|
||||||
new Permission(PermissionNames.Edit, RoleNames.Admin, true),
|
new Permission(PermissionNames.Edit, RoleNames.Admin, true),
|
||||||
}.EncodePermissions();
|
};
|
||||||
}
|
}
|
||||||
if (_userPermissions.IsAuthorized(User, PermissionNames.Edit, permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.Edit, permissions))
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
var installation = new Installation { Success = false, Message = "" };
|
var installation = new Installation { Success = false, Message = "" };
|
||||||
|
|
||||||
if (ModelState.IsValid && (User.IsInRole(RoleNames.Host) || string.IsNullOrEmpty(_configManager.GetSetting("ConnectionStrings:" + SettingKeys.ConnectionStringKey, ""))))
|
if (ModelState.IsValid && (User.IsInRole(RoleNames.Host) || string.IsNullOrEmpty(_configManager.GetSetting($"{SettingKeys.ConnectionStringsSection}:{SettingKeys.ConnectionStringKey}", ""))))
|
||||||
{
|
{
|
||||||
installation = _databaseManager.Install(config);
|
installation = _databaseManager.Install(config);
|
||||||
|
|
||||||
@ -120,6 +120,13 @@ namespace Oqtane.Controllers
|
|||||||
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||||
var assemblyList = new List<ClientAssembly>();
|
var assemblyList = new List<ClientAssembly>();
|
||||||
|
|
||||||
|
// testmode setting is used for validating that the API is downloading the appropriate assemblies to the client
|
||||||
|
bool hashfilename = true;
|
||||||
|
if (_configManager.GetSetting($"{SettingKeys.TestModeKey}", "false") == "true")
|
||||||
|
{
|
||||||
|
hashfilename = false;
|
||||||
|
}
|
||||||
|
|
||||||
// get list of assemblies which should be downloaded to client
|
// get list of assemblies which should be downloaded to client
|
||||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
|
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
|
||||||
var list = assemblies.Select(a => a.GetName().Name).ToList();
|
var list = assemblies.Select(a => a.GetName().Name).ToList();
|
||||||
@ -127,7 +134,7 @@ namespace Oqtane.Controllers
|
|||||||
// populate assemblies
|
// populate assemblies
|
||||||
for (int i = 0; i < list.Count; i++)
|
for (int i = 0; i < list.Count; i++)
|
||||||
{
|
{
|
||||||
assemblyList.Add(new ClientAssembly(Path.Combine(binFolder, list[i] + ".dll")));
|
assemblyList.Add(new ClientAssembly(Path.Combine(binFolder, list[i] + ".dll"), hashfilename));
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert satellite assemblies at beginning of list
|
// insert satellite assemblies at beginning of list
|
||||||
@ -143,7 +150,7 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
foreach (var resourceFile in Directory.EnumerateFiles(assembliesFolderPath))
|
foreach (var resourceFile in Directory.EnumerateFiles(assembliesFolderPath))
|
||||||
{
|
{
|
||||||
assemblyList.Insert(0, new ClientAssembly(resourceFile));
|
assemblyList.Insert(0, new ClientAssembly(resourceFile, hashfilename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -160,12 +167,12 @@ namespace Oqtane.Controllers
|
|||||||
var instance = Activator.CreateInstance(type) as IModule;
|
var instance = Activator.CreateInstance(type) as IModule;
|
||||||
foreach (string name in instance.ModuleDefinition.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Reverse())
|
foreach (string name in instance.ModuleDefinition.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Reverse())
|
||||||
{
|
{
|
||||||
var filepath = Path.Combine(binFolder, name + ".dll");
|
var filepath = Path.Combine(binFolder, name.ToLower().EndsWith(".dll") ? name : name + ".dll");
|
||||||
if (System.IO.File.Exists(filepath))
|
if (System.IO.File.Exists(filepath))
|
||||||
{
|
{
|
||||||
if (!assemblyList.Exists(item => item.FilePath == filepath))
|
if (!assemblyList.Exists(item => item.FilePath == filepath))
|
||||||
{
|
{
|
||||||
assemblyList.Insert(0, new ClientAssembly(filepath));
|
assemblyList.Insert(0, new ClientAssembly(filepath, hashfilename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -179,12 +186,12 @@ namespace Oqtane.Controllers
|
|||||||
var instance = Activator.CreateInstance(type) as ITheme;
|
var instance = Activator.CreateInstance(type) as ITheme;
|
||||||
foreach (string name in instance.Theme.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Reverse())
|
foreach (string name in instance.Theme.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Reverse())
|
||||||
{
|
{
|
||||||
var filepath = Path.Combine(binFolder, name + ".dll");
|
var filepath = Path.Combine(binFolder, name.ToLower().EndsWith(".dll") ? name : name + ".dll");
|
||||||
if (System.IO.File.Exists(filepath))
|
if (System.IO.File.Exists(filepath))
|
||||||
{
|
{
|
||||||
if (!assemblyList.Exists(item => item.FilePath == filepath))
|
if (!assemblyList.Exists(item => item.FilePath == filepath))
|
||||||
{
|
{
|
||||||
assemblyList.Insert(0, new ClientAssembly(filepath));
|
assemblyList.Insert(0, new ClientAssembly(filepath, hashfilename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -285,12 +292,19 @@ namespace Oqtane.Controllers
|
|||||||
|
|
||||||
public struct ClientAssembly
|
public struct ClientAssembly
|
||||||
{
|
{
|
||||||
public ClientAssembly(string filepath)
|
public ClientAssembly(string filepath, bool hashfilename)
|
||||||
{
|
{
|
||||||
FilePath = filepath;
|
FilePath = filepath;
|
||||||
DateTime lastwritetime = System.IO.File.GetLastWriteTime(filepath);
|
DateTime lastwritetime = System.IO.File.GetLastWriteTime(filepath);
|
||||||
|
if (hashfilename)
|
||||||
|
{
|
||||||
HashedName = GetDeterministicHashCode(filepath).ToString("X8") + "." + lastwritetime.ToString("yyyyMMddHHmmss") + Path.GetExtension(filepath);
|
HashedName = GetDeterministicHashCode(filepath).ToString("X8") + "." + lastwritetime.ToString("yyyyMMddHHmmss") + Path.GetExtension(filepath);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HashedName = Path.GetFileNameWithoutExtension(filepath) + "." + lastwritetime.ToString("yyyyMMddHHmmss") + Path.GetExtension(filepath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string FilePath { get; private set; }
|
public string FilePath { get; private set; }
|
||||||
public string HashedName { get; private set; }
|
public string HashedName { get; private set; }
|
||||||
|
@ -9,6 +9,7 @@ using Oqtane.Infrastructure;
|
|||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using Oqtane.Security;
|
using Oqtane.Security;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Security.Policy;
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
@ -47,17 +48,18 @@ namespace Oqtane.Controllers
|
|||||||
int SiteId;
|
int SiteId;
|
||||||
if (int.TryParse(siteid, out SiteId) && SiteId == _alias.SiteId)
|
if (int.TryParse(siteid, out SiteId) && SiteId == _alias.SiteId)
|
||||||
{
|
{
|
||||||
|
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(SiteId).ToList();
|
||||||
List<Setting> settings = _settings.GetSettings(EntityNames.Module).ToList();
|
List<Setting> settings = _settings.GetSettings(EntityNames.Module).ToList();
|
||||||
|
|
||||||
foreach (PageModule pagemodule in _pageModules.GetPageModules(SiteId))
|
foreach (PageModule pagemodule in _pageModules.GetPageModules(SiteId))
|
||||||
{
|
{
|
||||||
if (_userPermissions.IsAuthorized(User, PermissionNames.View, pagemodule.Module.Permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.View, pagemodule.Module.PermissionList))
|
||||||
{
|
{
|
||||||
Module module = new Module();
|
Module module = new Module();
|
||||||
module.SiteId = pagemodule.Module.SiteId;
|
module.SiteId = pagemodule.Module.SiteId;
|
||||||
module.ModuleDefinitionName = pagemodule.Module.ModuleDefinitionName;
|
module.ModuleDefinitionName = pagemodule.Module.ModuleDefinitionName;
|
||||||
module.AllPages = pagemodule.Module.AllPages;
|
module.AllPages = pagemodule.Module.AllPages;
|
||||||
module.Permissions = pagemodule.Module.Permissions;
|
module.PermissionList = pagemodule.Module.PermissionList;
|
||||||
module.CreatedBy = pagemodule.Module.CreatedBy;
|
module.CreatedBy = pagemodule.Module.CreatedBy;
|
||||||
module.CreatedOn = pagemodule.Module.CreatedOn;
|
module.CreatedOn = pagemodule.Module.CreatedOn;
|
||||||
module.ModifiedBy = pagemodule.Module.ModifiedBy;
|
module.ModifiedBy = pagemodule.Module.ModifiedBy;
|
||||||
@ -74,12 +76,15 @@ namespace Oqtane.Controllers
|
|||||||
module.Order = pagemodule.Order;
|
module.Order = pagemodule.Order;
|
||||||
module.ContainerType = pagemodule.ContainerType;
|
module.ContainerType = pagemodule.ContainerType;
|
||||||
|
|
||||||
|
module.ModuleDefinition = _moduleDefinitions.FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
||||||
|
|
||||||
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.Permissions))
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.PermissionList))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
|
|
||||||
modules.Add(module);
|
modules.Add(module);
|
||||||
}
|
}
|
||||||
|
modules = modules.OrderBy(item => item.PageId).ThenBy(item => item.Pane).ThenBy(item => item.Order).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -97,12 +102,12 @@ namespace Oqtane.Controllers
|
|||||||
public Module Get(int id)
|
public Module Get(int id)
|
||||||
{
|
{
|
||||||
Module module = _modules.GetModule(id);
|
Module module = _modules.GetModule(id);
|
||||||
if (module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User,PermissionNames.View, module.Permissions))
|
if (module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User,PermissionNames.View, module.PermissionList))
|
||||||
{
|
{
|
||||||
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
|
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
|
||||||
module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
module.ModuleDefinition = _moduleDefinitions.FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
||||||
module.Settings = _settings.GetSettings(EntityNames.Module, id)
|
module.Settings = _settings.GetSettings(EntityNames.Module, id)
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, module.Permissions))
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, module.PermissionList))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ using System;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using Oqtane.Modules;
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
@ -22,6 +23,9 @@ namespace Oqtane.Controllers
|
|||||||
public class ModuleDefinitionController : Controller
|
public class ModuleDefinitionController : Controller
|
||||||
{
|
{
|
||||||
private readonly IModuleDefinitionRepository _moduleDefinitions;
|
private readonly IModuleDefinitionRepository _moduleDefinitions;
|
||||||
|
private readonly IModuleRepository _modules;
|
||||||
|
private readonly IPageModuleRepository _pagemodules;
|
||||||
|
private readonly IPermissionRepository _permissions;
|
||||||
private readonly ITenantRepository _tenants;
|
private readonly ITenantRepository _tenants;
|
||||||
private readonly ISqlRepository _sql;
|
private readonly ISqlRepository _sql;
|
||||||
private readonly IUserPermissions _userPermissions;
|
private readonly IUserPermissions _userPermissions;
|
||||||
@ -33,9 +37,12 @@ namespace Oqtane.Controllers
|
|||||||
private readonly ILogManager _logger;
|
private readonly ILogManager _logger;
|
||||||
private readonly Alias _alias;
|
private readonly Alias _alias;
|
||||||
|
|
||||||
public ModuleDefinitionController(IModuleDefinitionRepository moduleDefinitions, ITenantRepository tenants, ISqlRepository sql, IUserPermissions userPermissions, IInstallationManager installationManager, IWebHostEnvironment environment, IServiceProvider serviceProvider, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger)
|
public ModuleDefinitionController(IModuleDefinitionRepository moduleDefinitions, IModuleRepository module, IPageModuleRepository pageModule, IPermissionRepository permission, ITenantRepository tenants, ISqlRepository sql, IUserPermissions userPermissions, IInstallationManager installationManager, IWebHostEnvironment environment, IServiceProvider serviceProvider, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger)
|
||||||
{
|
{
|
||||||
_moduleDefinitions = moduleDefinitions;
|
_moduleDefinitions = moduleDefinitions;
|
||||||
|
_modules = module;
|
||||||
|
_pagemodules = pageModule;
|
||||||
|
_permissions = permission;
|
||||||
_tenants = tenants;
|
_tenants = tenants;
|
||||||
_sql = sql;
|
_sql = sql;
|
||||||
_userPermissions = userPermissions;
|
_userPermissions = userPermissions;
|
||||||
@ -58,7 +65,7 @@ namespace Oqtane.Controllers
|
|||||||
List<ModuleDefinition> moduledefinitions = new List<ModuleDefinition>();
|
List<ModuleDefinition> moduledefinitions = new List<ModuleDefinition>();
|
||||||
foreach (ModuleDefinition moduledefinition in _moduleDefinitions.GetModuleDefinitions(SiteId))
|
foreach (ModuleDefinition moduledefinition in _moduleDefinitions.GetModuleDefinitions(SiteId))
|
||||||
{
|
{
|
||||||
if (_userPermissions.IsAuthorized(User, PermissionNames.Utilize, moduledefinition.Permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.Utilize, moduledefinition.PermissionList))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(moduledefinition.Version)) moduledefinition.Version = new Version(1, 0, 0).ToString();
|
if (string.IsNullOrEmpty(moduledefinition.Version)) moduledefinition.Version = new Version(1, 0, 0).ToString();
|
||||||
moduledefinitions.Add(moduledefinition);
|
moduledefinitions.Add(moduledefinition);
|
||||||
@ -82,7 +89,7 @@ namespace Oqtane.Controllers
|
|||||||
if (int.TryParse(siteid, out SiteId) && SiteId == _alias.SiteId)
|
if (int.TryParse(siteid, out SiteId) && SiteId == _alias.SiteId)
|
||||||
{
|
{
|
||||||
ModuleDefinition moduledefinition = _moduleDefinitions.GetModuleDefinition(id, SiteId);
|
ModuleDefinition moduledefinition = _moduleDefinitions.GetModuleDefinition(id, SiteId);
|
||||||
if (_userPermissions.IsAuthorized(User, PermissionNames.Utilize, moduledefinition.Permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.Utilize, moduledefinition.PermissionList))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(moduledefinition.Version)) moduledefinition.Version = new Version(1, 0, 0).ToString();
|
if (string.IsNullOrEmpty(moduledefinition.Version)) moduledefinition.Version = new Version(1, 0, 0).ToString();
|
||||||
return moduledefinition;
|
return moduledefinition;
|
||||||
@ -228,6 +235,27 @@ namespace Oqtane.Controllers
|
|||||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Static Resources Folder Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName);
|
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Static Resources Folder Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove PageModule and Module
|
||||||
|
List<Models.Module> modulesToRemove = _modules.GetModules(moduledefinition.SiteId).Where(m => m.ModuleDefinitionName == moduledefinition.ModuleDefinitionName).ToList();
|
||||||
|
foreach (Models.Module moduleToRemove in modulesToRemove)
|
||||||
|
{
|
||||||
|
// Get the PageModule items associated with the Module item to be removed
|
||||||
|
List<PageModule> pageModulesToRemove = _pagemodules.GetPageModules(moduledefinition.SiteId).Where(pm => pm.ModuleId == moduleToRemove.ModuleId).ToList();
|
||||||
|
|
||||||
|
foreach(PageModule pageModule in pageModulesToRemove)
|
||||||
|
{
|
||||||
|
// Remove the PageModule item
|
||||||
|
_pagemodules.DeletePageModule(pageModule.PageModuleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove Permissions
|
||||||
|
_permissions.DeletePermissions(moduledefinition.SiteId, EntityNames.Module, moduleToRemove.ModuleId);
|
||||||
|
|
||||||
|
// Remove the Module item
|
||||||
|
_modules.DeleteModule(moduleToRemove.ModuleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// remove module definition
|
// remove module definition
|
||||||
_moduleDefinitions.DeleteModuleDefinition(id);
|
_moduleDefinitions.DeleteModuleDefinition(id);
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId, SyncEventActions.Delete);
|
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId, SyncEventActions.Delete);
|
||||||
@ -240,14 +268,6 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("install")]
|
|
||||||
[Authorize(Roles = RoleNames.Host)]
|
|
||||||
public void InstallModules()
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Modules Installed");
|
|
||||||
_installationManager.InstallPackages();
|
|
||||||
}
|
|
||||||
|
|
||||||
// GET: api/<controller>/templates
|
// GET: api/<controller>/templates
|
||||||
[HttpGet("templates")]
|
[HttpGet("templates")]
|
||||||
[Authorize(Roles = RoleNames.Host)]
|
[Authorize(Roles = RoleNames.Host)]
|
||||||
|
@ -54,10 +54,10 @@ namespace Oqtane.Controllers
|
|||||||
|
|
||||||
foreach (Page page in _pages.GetPages(SiteId))
|
foreach (Page page in _pages.GetPages(SiteId))
|
||||||
{
|
{
|
||||||
if (_userPermissions.IsAuthorized(User, PermissionNames.View, page.Permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.View, page.PermissionList))
|
||||||
{
|
{
|
||||||
page.Settings = settings.Where(item => item.EntityId == page.PageId)
|
page.Settings = settings.Where(item => item.EntityId == page.PageId)
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.Permissions))
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.PermissionList))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
pages.Add(page);
|
pages.Add(page);
|
||||||
}
|
}
|
||||||
@ -86,10 +86,10 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
page = _pages.GetPage(id, int.Parse(userid));
|
page = _pages.GetPage(id, int.Parse(userid));
|
||||||
}
|
}
|
||||||
if (page != null && page.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User,PermissionNames.View, page.Permissions))
|
if (page != null && page.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, page.PermissionList))
|
||||||
{
|
{
|
||||||
page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId)
|
page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId)
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.Permissions))
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.PermissionList))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
@ -106,10 +106,10 @@ namespace Oqtane.Controllers
|
|||||||
public Page Get(string path, int siteid)
|
public Page Get(string path, int siteid)
|
||||||
{
|
{
|
||||||
Page page = _pages.GetPage(WebUtility.UrlDecode(path), siteid);
|
Page page = _pages.GetPage(WebUtility.UrlDecode(path), siteid);
|
||||||
if (page != null && page.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, page.Permissions))
|
if (page != null && page.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, page.PermissionList))
|
||||||
{
|
{
|
||||||
page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId)
|
page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId)
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.Permissions))
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.PermissionList))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
@ -128,16 +128,16 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
if (ModelState.IsValid && page.SiteId == _alias.SiteId)
|
if (ModelState.IsValid && page.SiteId == _alias.SiteId)
|
||||||
{
|
{
|
||||||
string permissions;
|
List<Permission> permissions;
|
||||||
if (page.ParentId != null)
|
if (page.ParentId != null)
|
||||||
{
|
{
|
||||||
permissions = _pages.GetPage(page.ParentId.Value).Permissions;
|
permissions = _pages.GetPage(page.ParentId.Value).PermissionList;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
permissions = new List<Permission> {
|
permissions = new List<Permission> {
|
||||||
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
||||||
}.EncodePermissions();
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_userPermissions.IsAuthorized(User, PermissionNames.Edit, permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.Edit, permissions))
|
||||||
@ -194,10 +194,10 @@ namespace Oqtane.Controllers
|
|||||||
page.ThemeType = parent.ThemeType;
|
page.ThemeType = parent.ThemeType;
|
||||||
page.DefaultContainerType = parent.DefaultContainerType;
|
page.DefaultContainerType = parent.DefaultContainerType;
|
||||||
page.Icon = parent.Icon;
|
page.Icon = parent.Icon;
|
||||||
page.Permissions = new List<Permission> {
|
page.PermissionList = new List<Permission> {
|
||||||
new Permission(PermissionNames.View, int.Parse(userid), true),
|
new Permission(PermissionNames.View, int.Parse(userid), true),
|
||||||
new Permission(PermissionNames.Edit, int.Parse(userid), true)
|
new Permission(PermissionNames.Edit, int.Parse(userid), true)
|
||||||
}.EncodePermissions();
|
};
|
||||||
page.IsPersonalizable = false;
|
page.IsPersonalizable = false;
|
||||||
page.UserId = int.Parse(userid);
|
page.UserId = int.Parse(userid);
|
||||||
page = _pages.AddPage(page);
|
page = _pages.AddPage(page);
|
||||||
@ -213,10 +213,10 @@ namespace Oqtane.Controllers
|
|||||||
module.PageId = page.PageId;
|
module.PageId = page.PageId;
|
||||||
module.ModuleDefinitionName = pm.Module.ModuleDefinitionName;
|
module.ModuleDefinitionName = pm.Module.ModuleDefinitionName;
|
||||||
module.AllPages = false;
|
module.AllPages = false;
|
||||||
module.Permissions = new List<Permission> {
|
module.PermissionList = new List<Permission> {
|
||||||
new Permission(PermissionNames.View, int.Parse(userid), true),
|
new Permission(PermissionNames.View, int.Parse(userid), true),
|
||||||
new Permission(PermissionNames.Edit, int.Parse(userid), true)
|
new Permission(PermissionNames.Edit, int.Parse(userid), true)
|
||||||
}.EncodePermissions();
|
};
|
||||||
module = _modules.AddModule(module);
|
module = _modules.AddModule(module);
|
||||||
|
|
||||||
string content = _modules.ExportModule(pm.ModuleId);
|
string content = _modules.ExportModule(pm.ModuleId);
|
||||||
@ -274,9 +274,8 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get differences between current and new page permissions
|
// get differences between current and new page permissions
|
||||||
var newPermissions = _permissionRepository.DecodePermissions(page.Permissions, page.SiteId, EntityNames.Page, page.PageId).ToList();
|
var added = GetPermissionsDifferences(page.PermissionList, currentPermissions);
|
||||||
var added = GetPermissionsDifferences(newPermissions, currentPermissions);
|
var removed = GetPermissionsDifferences(currentPermissions, page.PermissionList);
|
||||||
var removed = GetPermissionsDifferences(currentPermissions, newPermissions);
|
|
||||||
|
|
||||||
// synchronize module permissions
|
// synchronize module permissions
|
||||||
if (added.Count > 0 || removed.Count > 0)
|
if (added.Count > 0 || removed.Count > 0)
|
||||||
@ -346,7 +345,7 @@ namespace Oqtane.Controllers
|
|||||||
[Authorize(Roles = RoleNames.Registered)]
|
[Authorize(Roles = RoleNames.Registered)]
|
||||||
public void Put(int siteid, int pageid, int? parentid)
|
public void Put(int siteid, int pageid, int? parentid)
|
||||||
{
|
{
|
||||||
if (siteid == _alias.SiteId && siteid == _alias.SiteId && _pages.GetPage(pageid, false) != null && _userPermissions.IsAuthorized(User, siteid, EntityNames.Page, pageid, PermissionNames.Edit))
|
if (siteid == _alias.SiteId && _pages.GetPage(pageid, false) != null && _userPermissions.IsAuthorized(User, siteid, EntityNames.Page, pageid, PermissionNames.Edit))
|
||||||
{
|
{
|
||||||
int order = 1;
|
int order = 1;
|
||||||
List<Page> pages = _pages.GetPages(siteid).ToList();
|
List<Page> pages = _pages.GetPages(siteid).ToList();
|
||||||
|
@ -38,7 +38,7 @@ namespace Oqtane.Controllers
|
|||||||
public PageModule Get(int id)
|
public PageModule Get(int id)
|
||||||
{
|
{
|
||||||
PageModule pagemodule = _pageModules.GetPageModule(id);
|
PageModule pagemodule = _pageModules.GetPageModule(id);
|
||||||
if (pagemodule != null && pagemodule.Module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, pagemodule.Module.Permissions))
|
if (pagemodule != null && pagemodule.Module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, pagemodule.Module.PermissionList))
|
||||||
{
|
{
|
||||||
return pagemodule;
|
return pagemodule;
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ namespace Oqtane.Controllers
|
|||||||
public PageModule Get(int pageid, int moduleid)
|
public PageModule Get(int pageid, int moduleid)
|
||||||
{
|
{
|
||||||
PageModule pagemodule = _pageModules.GetPageModule(pageid, moduleid);
|
PageModule pagemodule = _pageModules.GetPageModule(pageid, moduleid);
|
||||||
if (pagemodule != null && pagemodule.Module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, pagemodule.Module.Permissions))
|
if (pagemodule != null && pagemodule.Module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, pagemodule.Module.PermissionList))
|
||||||
{
|
{
|
||||||
return pagemodule;
|
return pagemodule;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ namespace Oqtane.Controllers
|
|||||||
_identityCache = identityCache;
|
_identityCache = identityCache;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_alias = tenantManager.GetAlias();
|
_alias = tenantManager.GetAlias();
|
||||||
_visitorCookie = "APP_VISITOR_" + _alias.SiteId.ToString();
|
_visitorCookie = Constants.VisitorCookiePrefix + _alias.SiteId.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET: api/<controller>
|
// GET: api/<controller>
|
||||||
@ -63,10 +63,14 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// suppress unauthorized visitor logging as it is usually caused by clients that do not support cookies
|
||||||
|
if (entityName != EntityNames.Visitor)
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Settings {EntityName} {EntityId}", entityName, entityId);
|
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Settings {EntityName} {EntityId}", entityName, entityId);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,9 +88,12 @@ namespace Oqtane.Controllers
|
|||||||
return setting;
|
return setting;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (entityName != EntityNames.Visitor)
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Setting {EntityName} {SettingId}", entityName, id);
|
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Setting {EntityName} {SettingId}", entityName, id);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,9 +109,12 @@ namespace Oqtane.Controllers
|
|||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Setting Added {Setting}", setting);
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Setting Added {Setting}", setting);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (setting.EntityName != EntityNames.Visitor)
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Add Setting {Setting}", setting);
|
_logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Add Setting {Setting}", setting);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
|
}
|
||||||
setting = null;
|
setting = null;
|
||||||
}
|
}
|
||||||
return setting;
|
return setting;
|
||||||
@ -121,9 +131,12 @@ namespace Oqtane.Controllers
|
|||||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Setting Updated {Setting}", setting);
|
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Setting Updated {Setting}", setting);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (setting.EntityName != EntityNames.Visitor)
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Setting {Setting}", setting);
|
_logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Setting {Setting}", setting);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
|
}
|
||||||
setting = null;
|
setting = null;
|
||||||
}
|
}
|
||||||
return setting;
|
return setting;
|
||||||
@ -141,11 +154,14 @@ namespace Oqtane.Controllers
|
|||||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Setting Deleted {Setting}", setting);
|
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Setting Deleted {Setting}", setting);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (entityName != EntityNames.Visitor)
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Delete, "User Not Authorized To Delete Setting {Setting}", setting);
|
_logger.Log(LogLevel.Error, this, LogFunction.Delete, "User Not Authorized To Delete Setting {Setting}", setting);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DELETE api/<controller>/clear
|
// DELETE api/<controller>/clear
|
||||||
[HttpDelete("clear")]
|
[HttpDelete("clear")]
|
||||||
@ -219,6 +235,7 @@ namespace Oqtane.Controllers
|
|||||||
authorized = User.IsInRole(RoleNames.Admin);
|
authorized = User.IsInRole(RoleNames.Admin);
|
||||||
if (!authorized)
|
if (!authorized)
|
||||||
{
|
{
|
||||||
|
// a visitor may have cookies disabled
|
||||||
if (int.TryParse(Request.Cookies[_visitorCookie], out int visitorId))
|
if (int.TryParse(Request.Cookies[_visitorCookie], out int visitorId))
|
||||||
{
|
{
|
||||||
authorized = (visitorId == entityId);
|
authorized = (visitorId == entityId);
|
||||||
|
@ -89,10 +89,10 @@ namespace Oqtane.Controllers
|
|||||||
site.Pages = new List<Page>();
|
site.Pages = new List<Page>();
|
||||||
foreach (Page page in _pages.GetPages(site.SiteId))
|
foreach (Page page in _pages.GetPages(site.SiteId))
|
||||||
{
|
{
|
||||||
if (_userPermissions.IsAuthorized(User, PermissionNames.View, page.Permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.View, page.PermissionList))
|
||||||
{
|
{
|
||||||
page.Settings = settings.Where(item => item.EntityId == page.PageId)
|
page.Settings = settings.Where(item => item.EntityId == page.PageId)
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.Permissions))
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.PermissionList))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
site.Pages.Add(page);
|
site.Pages.Add(page);
|
||||||
}
|
}
|
||||||
@ -105,13 +105,13 @@ namespace Oqtane.Controllers
|
|||||||
site.Modules = new List<Module>();
|
site.Modules = new List<Module>();
|
||||||
foreach (PageModule pagemodule in _pageModules.GetPageModules(site.SiteId))
|
foreach (PageModule pagemodule in _pageModules.GetPageModules(site.SiteId))
|
||||||
{
|
{
|
||||||
if (_userPermissions.IsAuthorized(User, PermissionNames.View, pagemodule.Module.Permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.View, pagemodule.Module.PermissionList))
|
||||||
{
|
{
|
||||||
Module module = new Module();
|
Module module = new Module();
|
||||||
module.SiteId = pagemodule.Module.SiteId;
|
module.SiteId = pagemodule.Module.SiteId;
|
||||||
module.ModuleDefinitionName = pagemodule.Module.ModuleDefinitionName;
|
module.ModuleDefinitionName = pagemodule.Module.ModuleDefinitionName;
|
||||||
module.AllPages = pagemodule.Module.AllPages;
|
module.AllPages = pagemodule.Module.AllPages;
|
||||||
module.Permissions = pagemodule.Module.Permissions;
|
module.PermissionList = pagemodule.Module.PermissionList;
|
||||||
module.CreatedBy = pagemodule.Module.CreatedBy;
|
module.CreatedBy = pagemodule.Module.CreatedBy;
|
||||||
module.CreatedOn = pagemodule.Module.CreatedOn;
|
module.CreatedOn = pagemodule.Module.CreatedOn;
|
||||||
module.ModifiedBy = pagemodule.Module.ModifiedBy;
|
module.ModifiedBy = pagemodule.Module.ModifiedBy;
|
||||||
@ -128,14 +128,16 @@ namespace Oqtane.Controllers
|
|||||||
module.Order = pagemodule.Order;
|
module.Order = pagemodule.Order;
|
||||||
module.ContainerType = pagemodule.ContainerType;
|
module.ContainerType = pagemodule.ContainerType;
|
||||||
|
|
||||||
module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
module.ModuleDefinition = _moduleDefinitions.FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
||||||
|
|
||||||
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.Permissions))
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.PermissionList))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
|
|
||||||
site.Modules.Add(module);
|
site.Modules.Add(module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
site.Modules = site.Modules.OrderBy(item => item.PageId).ThenBy(item => item.Pane).ThenBy(item => item.Order).ToList();
|
||||||
|
|
||||||
// languages
|
// languages
|
||||||
site.Languages = _languages.GetLanguages(site.SiteId).ToList();
|
site.Languages = _languages.GetLanguages(site.SiteId).ToList();
|
||||||
|
@ -32,13 +32,23 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
var results = new List<Dictionary<string, string>>();
|
var results = new List<Dictionary<string, string>>();
|
||||||
Dictionary<string, string> row;
|
Dictionary<string, string> row;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(sqlquery.DBType) || string.IsNullOrEmpty(sqlquery.DBConnectionString))
|
||||||
|
{
|
||||||
Tenant tenant = _tenants.GetTenant(sqlquery.TenantId);
|
Tenant tenant = _tenants.GetTenant(sqlquery.TenantId);
|
||||||
|
if (tenant != null)
|
||||||
|
{
|
||||||
|
sqlquery.DBType = tenant.DBType;
|
||||||
|
sqlquery.DBConnectionString = tenant.DBConnectionString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach (string query in sqlquery.Query.Split("GO", StringSplitOptions.RemoveEmptyEntries))
|
foreach (string query in sqlquery.Query.Split("GO", StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
IDataReader dr = _sql.ExecuteReader(tenant, query);
|
IDataReader dr = _sql.ExecuteReader(sqlquery.DBType, sqlquery.DBConnectionString, query);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Other, "Sql Query {Query} Executed on Tenant {TenantId}", query, sqlquery.TenantId);
|
_logger.Log(LogLevel.Information, this, LogFunction.Other, "Sql Query {Query} Executed on Database {DBType} and Connection {DBConnectionString}", query, sqlquery.DBType, sqlquery.DBConnectionString);
|
||||||
while (dr.Read())
|
while (dr.Read())
|
||||||
{
|
{
|
||||||
row = new Dictionary<string, string>();
|
row = new Dictionary<string, string>();
|
||||||
@ -53,7 +63,7 @@ namespace Oqtane.Controllers
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
results.Add(new Dictionary<string, string>() { { "Error", ex.Message } });
|
results.Add(new Dictionary<string, string>() { { "Error", ex.Message } });
|
||||||
_logger.Log(LogLevel.Warning, this, LogFunction.Other, "Sql Query {Query} Executed on Tenant {TenantId} Resulted In An Error {Error}", sqlquery.Query, sqlquery.TenantId, ex.Message);
|
_logger.Log(LogLevel.Warning, this, LogFunction.Other, "Sql Query {Query} Executed on Database {DBType} and Connection {DBConnectionString} Resulted In An Error {Error}", sqlquery.Query, sqlquery.DBType, sqlquery.DBConnectionString, ex.Message);
|
||||||
}
|
}
|
||||||
sqlquery.Results = results;
|
sqlquery.Results = results;
|
||||||
return sqlquery;
|
return sqlquery;
|
||||||
|
@ -63,6 +63,12 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
systeminfo.Add("Log", log);
|
systeminfo.Add("Log", log);
|
||||||
break;
|
break;
|
||||||
|
case "connectionstrings":
|
||||||
|
foreach (var kvp in _configManager.GetSettings(SettingKeys.ConnectionStringsSection))
|
||||||
|
{
|
||||||
|
systeminfo.Add(kvp.Key, kvp.Value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return systeminfo;
|
return systeminfo;
|
||||||
@ -84,16 +90,25 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
foreach(KeyValuePair<string, object> kvp in settings)
|
foreach(KeyValuePair<string, object> kvp in settings)
|
||||||
{
|
{
|
||||||
_configManager.AddOrUpdateSetting(kvp.Key, kvp.Value, false);
|
UpdateSetting(kvp.Key, kvp.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUT: api/<controller>
|
private void UpdateSetting(string key, object value)
|
||||||
[HttpPut("{key}/{value}")]
|
|
||||||
[Authorize(Roles = RoleNames.Host)]
|
|
||||||
public void Put(string key, object value)
|
|
||||||
{
|
{
|
||||||
|
switch (key.ToLower())
|
||||||
|
{
|
||||||
|
case "clearlog":
|
||||||
|
string path = Path.Combine(_environment.ContentRootPath, "Content", "Log", "error.log");
|
||||||
|
if (System.IO.File.Exists(path))
|
||||||
|
{
|
||||||
|
System.IO.File.Delete(path);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
_configManager.AddOrUpdateSetting(key, value, false);
|
_configManager.AddOrUpdateSetting(key, value, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,14 +41,6 @@ namespace Oqtane.Controllers
|
|||||||
return _themes.GetThemes();
|
return _themes.GetThemes();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("install")]
|
|
||||||
[Authorize(Roles = RoleNames.Host)]
|
|
||||||
public void InstallThemes()
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Themes Installed");
|
|
||||||
_installationManager.InstallPackages();
|
|
||||||
}
|
|
||||||
|
|
||||||
// DELETE api/<controller>/xxx
|
// DELETE api/<controller>/xxx
|
||||||
[HttpDelete("{themename}")]
|
[HttpDelete("{themename}")]
|
||||||
[Authorize(Roles = RoleNames.Host)]
|
[Authorize(Roles = RoleNames.Host)]
|
||||||
|
@ -330,11 +330,11 @@ namespace Oqtane.Controllers
|
|||||||
// delete user
|
// delete user
|
||||||
_users.DeleteUser(user.UserId);
|
_users.DeleteUser(user.UserId);
|
||||||
_syncManager.AddSyncEvent(_tenantManager.GetAlias().TenantId, EntityNames.User, user.UserId, SyncEventActions.Delete);
|
_syncManager.AddSyncEvent(_tenantManager.GetAlias().TenantId, EntityNames.User, user.UserId, SyncEventActions.Delete);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Deleted {UserId}", user.UserId);
|
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Deleted {UserId}", user.UserId, result.ToString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Delete, "Error Deleting User {UserId}", user.UserId, result.ToString());
|
_logger.Log(LogLevel.Error, this, LogFunction.Delete, "Error Deleting User {UserId}", user.UserId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ namespace Oqtane.Controllers
|
|||||||
bool authorized = User.IsInRole(RoleNames.Admin);
|
bool authorized = User.IsInRole(RoleNames.Admin);
|
||||||
if (!authorized)
|
if (!authorized)
|
||||||
{
|
{
|
||||||
var visitorCookie = "APP_VISITOR_" + _alias.SiteId.ToString();
|
var visitorCookie = Constants.VisitorCookiePrefix + _alias.SiteId.ToString();
|
||||||
if (int.TryParse(Request.Cookies[visitorCookie], out int visitorId))
|
if (int.TryParse(Request.Cookies[visitorCookie], out int visitorId))
|
||||||
{
|
{
|
||||||
authorized = (visitorId == id);
|
authorized = (visitorId == id);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user