Compare commits
317 Commits
Author | SHA1 | Date | |
---|---|---|---|
07ae0edd30 | |||
32e8052079 | |||
60ccad3106 | |||
bcc00a2dbb | |||
5080040590 | |||
0d71a3878f | |||
82b16d28ff | |||
e34ffb716d | |||
6f8c2fb2ed | |||
3970722abf | |||
880ad0486a | |||
a02786b8b0 | |||
2bea59fc66 | |||
45819aae07 | |||
4762fac0ce | |||
8b97872100 | |||
b921ec24ab | |||
07519bccde | |||
a8932ec1e0 | |||
a9bb82347d | |||
2c58a97ec1 | |||
41b30bfab2 | |||
a77aa5fe18 | |||
780b0c704c | |||
26c054c22d | |||
047336ad21 | |||
2d344975ff | |||
e0017065af | |||
f0a9739b37 | |||
5e801bd5ee | |||
824df0e849 | |||
a24fd099c0 | |||
c6fdc99690 | |||
b602113cd1 | |||
b6886116ad | |||
f976910730 | |||
6726a42406 | |||
23a35cf3c4 | |||
f5b99bf9d1 | |||
d7135ad4f9 | |||
0d03f59cd4 | |||
5b49e1bc7c | |||
a3215e286a | |||
b10140f513 | |||
8eaa298d8b | |||
c52d255a30 | |||
97cec46ec1 | |||
46c1564e3d | |||
700b6e2d68 | |||
3cfb27b2bc | |||
b4b73b7e5a | |||
8c2338e590 | |||
89875516e6 | |||
15aa2c2e47 | |||
1bf4bd0022 | |||
570b885c09 | |||
90de3949d2 | |||
38eb7c05b3 | |||
5948e7ba76 | |||
3cbf55e1ce | |||
ec270fbff0 | |||
03926bccb0 | |||
cdb7de84fa | |||
76eccececa | |||
2f17945020 | |||
cbd7caa6df | |||
0ef04e81ff | |||
4dbe16bee5 | |||
3f78c99ed4 | |||
eaa8649699 | |||
5835e037a7 | |||
af41e8bcfb | |||
d19f3f358b | |||
fc7000394f | |||
892b79833b | |||
ef51d5f05d | |||
40d8315cff | |||
544475c489 | |||
e61cd3d366 | |||
01fc60d35d | |||
17a9710c14 | |||
8cf846ba90 | |||
70a345d2a9 | |||
79b584f268 | |||
3b09699618 | |||
1315e0382e | |||
c733707adc | |||
9294537e23 | |||
2abc2cdf20 | |||
ecacb681b4 | |||
34b9903b15 | |||
fed56098a0 | |||
fd5d777d3a | |||
5bb7c63d44 | |||
34122a344d | |||
74026401a6 | |||
f5beb54ddb | |||
d082c5427b | |||
f3e2177423 | |||
7c8beac3dc | |||
1293b98226 | |||
63f43bc27e | |||
f9296ec5c5 | |||
9543cd7031 | |||
857d699c0d | |||
c683de2cda | |||
3e71bdfef3 | |||
766be6c929 | |||
f33fb4d001 | |||
becc779db8 | |||
955e7a3856 | |||
06c041dd4e | |||
4a90e6e64f | |||
81475fd835 | |||
edc65e66c9 | |||
4b11bdc4be | |||
67067a884b | |||
86bb6d1ea8 | |||
7b1a2fb887 | |||
b3db92ee95 | |||
aad10ab1c4 | |||
3ab9510e2a | |||
fde43b6c39 | |||
7b3dfc49b2 | |||
0a9edd8916 | |||
0c0916c6ab | |||
ece8f3a57e | |||
3d7630d3d4 | |||
8b6d0d3c7f | |||
ce37d2f2d2 | |||
40524300bf | |||
5ae9daf5f2 | |||
6a7be12758 | |||
bcb6c81e43 | |||
26c40fb367 | |||
e934a28c39 | |||
c2ca55627e | |||
4a6ffacf56 | |||
bc72e28d11 | |||
2a402497cf | |||
49985dcf9e | |||
666721bf1a | |||
5f56bc288b | |||
6e41cd850e | |||
f70fed66ae | |||
2e2d46996a | |||
f83c1b1741 | |||
2924e7849f | |||
437170671f | |||
b52dd571ee | |||
ad9146ead1 | |||
52d1d5841e | |||
468327d597 | |||
7f28c5f2ff | |||
accf947afd | |||
ec73c958c9 | |||
396d584615 | |||
edecfa10cd | |||
0796ce54a9 | |||
0044f031aa | |||
913ad53302 | |||
ad5f5fbc24 | |||
14746f47da | |||
0d76070663 | |||
c01cd3b46c | |||
3613ce62eb | |||
61839d8e46 | |||
8196112a59 | |||
465cbe3c96 | |||
38f2fa5733 | |||
7f15a5f464 | |||
0c5d992d18 | |||
57dd983c1f | |||
d89927ca96 | |||
63744d9ec2 | |||
c67526b5b0 | |||
1cb6bf2a6b | |||
ac9969c1b6 | |||
510cd23d5e | |||
c94ccbff69 | |||
93d0cc5e1a | |||
075ea0aafd | |||
e75fe19103 | |||
e76f1b9663 | |||
cb1c725ec1 | |||
98cd361fc0 | |||
d0c8399dd9 | |||
4effa8ec66 | |||
4065d87a74 | |||
eb9acc770c | |||
a8cd84e798 | |||
74e5b83026 | |||
4aa0b83807 | |||
fd592e8d9f | |||
bb21eba39f | |||
b09cb9d655 | |||
bbbe48b976 | |||
a036ee19a4 | |||
5b45c79357 | |||
760fc3b8d4 | |||
fc50a45ecd | |||
e3fe8c5914 | |||
2624b9c105 | |||
2f9f823330 | |||
6cc144d733 | |||
df404c12a4 | |||
faec53b3c5 | |||
e1ec58b297 | |||
69abce7ce4 | |||
38738e0844 | |||
abe0a1a806 | |||
809946685a | |||
20c8f1528d | |||
282579fcf2 | |||
c8e3fa88e7 | |||
aec5882de1 | |||
bc231b18cf | |||
6bcb769fe5 | |||
90110a653c | |||
3c561cc413 | |||
73f9622ba2 | |||
cf198ff781 | |||
648fc56495 | |||
ea6dc6b983 | |||
c0e8d09ce1 | |||
a471784cf3 | |||
1d2a4bf484 | |||
3fa620f3bc | |||
35f186b532 | |||
5cf35fd70a | |||
1eef08eaeb | |||
1750f28a9f | |||
41edbc5e22 | |||
04257f75e7 | |||
5fb602f733 | |||
94f0bdcce9 | |||
0ba24f9a3a | |||
aac7d6b97a | |||
bcc33af52b | |||
24fd42636a | |||
8d539d058c | |||
abda377f6f | |||
51bf822392 | |||
d3f135a9c7 | |||
07ba99cc41 | |||
336550c571 | |||
679cc04178 | |||
75fe4e7c89 | |||
410f8c74e5 | |||
05f67d6a2a | |||
3a6cde0e24 | |||
fe1de2b243 | |||
62a6b5f28a | |||
d648fa0f02 | |||
e706e8cf1f | |||
9eb8a7e65c | |||
11c610edf0 | |||
a65cdbd7ad | |||
97c56ba142 | |||
9fe72a1c98 | |||
7b40725534 | |||
5e1671afe3 | |||
50d74cbcee | |||
bc73e5e3d0 | |||
b02bdee8cb | |||
9db4985b14 | |||
6f281c256b | |||
807252c9e5 | |||
23e7f66188 | |||
57c500f4bc | |||
fe302aa9e4 | |||
f14f927df7 | |||
c3f74a5217 | |||
457d1bb563 | |||
25918056cb | |||
86517dd793 | |||
00ce083a2c | |||
bce262cd8e | |||
b5db62ef6a | |||
3703d87d50 | |||
f515def414 | |||
4bdf20822f | |||
49f4e64cb4 | |||
e615263706 | |||
2a7e256116 | |||
a083405b48 | |||
3ea280c82a | |||
192433f02d | |||
56a2e9dcea | |||
921cced1c8 | |||
b17f679f38 | |||
8e43fcab21 | |||
73c5092e46 | |||
56537e4785 | |||
3bd7d7196d | |||
7b5a192b82 | |||
d4be058d07 | |||
6c20fea46a | |||
2e7cfefb2e | |||
038894cf64 | |||
954e30d89f | |||
93d9c4534d | |||
468ca8c6a9 | |||
e7a4c08dea | |||
69d639ee42 | |||
a780569a6f | |||
568c283efd | |||
fccdd07a08 | |||
5e816ea912 | |||
cb2d529689 | |||
c5037e7084 | |||
fdc39d57fb | |||
4960e2c668 | |||
66cc3a1392 | |||
6e7c8e7b05 | |||
727b943fa3 | |||
a4a0334ec0 |
2
.deployment
Normal file
2
.deployment
Normal file
@ -0,0 +1,2 @@
|
||||
[config]
|
||||
project = Oqtane.Server/Oqtane.Server.csproj
|
53
.editorconfig
Normal file
53
.editorconfig
Normal file
@ -0,0 +1,53 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = crlf
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{json,csproj,props,targets}]
|
||||
indent_size = 2
|
||||
|
||||
[*.cs]
|
||||
# Prefer "var" everywhere
|
||||
csharp_style_var_for_built_in_types = true : suggestion
|
||||
csharp_style_var_when_type_is_apparent = true : suggestion
|
||||
csharp_style_var_elsewhere = true : suggestion
|
||||
|
||||
# Newline settings
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
|
||||
# Sort using and Import directives with System.* appearing first
|
||||
dotnet_sort_system_directives_first = true
|
||||
|
||||
# Avoid "this." if not necessary
|
||||
dotnet_style_qualification_for_field = false : suggestion
|
||||
dotnet_style_qualification_for_property = false : suggestion
|
||||
dotnet_style_qualification_for_method = false : suggestion
|
||||
dotnet_style_qualification_for_event = false : suggestion
|
||||
|
||||
# Use language keywords instead of framework type names for type references
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true : suggestion
|
||||
dotnet_style_predefined_type_for_member_access = false : suggestion
|
||||
|
||||
# Suggest more modern language features when available
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true : none
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true : none
|
||||
csharp_style_inlined_variable_declaration = true : none
|
||||
csharp_style_throw_expression = true : none
|
||||
csharp_style_conditional_delegate_call = true : none
|
||||
|
||||
dotnet_style_object_initializer = true : suggestion
|
||||
dotnet_style_collection_initializer = true : suggestion
|
||||
dotnet_style_coalesce_expression = true : suggestion
|
||||
dotnet_style_null_propagation = true : suggestion
|
||||
dotnet_style_explicit_tuple_names = true : suggestion
|
||||
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
3
Oqtane.Client/AssemblyInfo.cs
Normal file
3
Oqtane.Client/AssemblyInfo.cs
Normal file
@ -0,0 +1,3 @@
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
[assembly: RootNamespace("Oqtane")]
|
@ -8,7 +8,7 @@
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Module module = await ModuleService.GetModuleAsync(ModuleState.ModuleId);
|
||||
if (UserSecurity.IsAuthorized(PageState.User, Constants.HostRole))
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
string message = "A Problem Was Encountered Loading Module " + module.ModuleDefinitionName;
|
||||
AddModuleMessage(message, MessageType.Error);
|
||||
|
111
Oqtane.Client/Modules/Admin/Files/Details.razor
Normal file
111
Oqtane.Client/Modules/Admin/Files/Details.razor
Normal file
@ -0,0 +1,111 @@
|
||||
@namespace Oqtane.Modules.Admin.Files
|
||||
@inherits ModuleBase
|
||||
@inject IFileService FileService
|
||||
@inject IFolderService FolderService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@if (_folders != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label for="name" HelpText="The name of the file">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="parent" HelpText="The folder where the file is located">Folder: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="parent" class="form-control" @bind="@_folderId">
|
||||
@foreach (Folder folder in _folders)
|
||||
{
|
||||
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label for="size" HelpText="The size of the file (in bytes)">Size: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="size" class="form-control" @bind="@_size" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveFile">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@_createdBy" CreatedOn="@_createdOn" ModifiedBy="@_modifiedBy" ModifiedOn="@_modifiedOn"></AuditInfo>
|
||||
}
|
||||
|
||||
@code {
|
||||
private int _fileId = -1;
|
||||
private string _name;
|
||||
private List<Folder> _folders;
|
||||
private int _folderId = -1;
|
||||
private int _size;
|
||||
private string _createdBy;
|
||||
private DateTime _createdOn;
|
||||
private string _modifiedBy;
|
||||
private DateTime _modifiedOn;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
public override string Title => "File Management";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_folders = await FolderService.GetFoldersAsync(PageState.Site.SiteId);
|
||||
_fileId = Int32.Parse(PageState.QueryString["id"]);
|
||||
File file = await FileService.GetFileAsync(_fileId);
|
||||
if (file != null)
|
||||
{
|
||||
_name = file.Name;
|
||||
_folderId = file.FolderId;
|
||||
_size = file.Size;
|
||||
_createdBy = file.CreatedBy;
|
||||
_createdOn = file.CreatedOn;
|
||||
_modifiedBy = file.ModifiedBy;
|
||||
_modifiedOn = file.ModifiedOn;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading File {FileId} {Error}", _fileId, ex.Message);
|
||||
AddModuleMessage("Error Loading File", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveFile()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_name.IsPathOrFileValid())
|
||||
{
|
||||
File file = await FileService.GetFileAsync(_fileId);
|
||||
file.Name = _name;
|
||||
file.FolderId = _folderId;
|
||||
file = await FileService.UpdateFileAsync(file);
|
||||
await logger.LogInformation("File Saved {File}", file);
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("File Name Not Valid", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Saving File {FileId} {Error}", _fileId, ex.Message);
|
||||
AddModuleMessage("Error Saving File", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
@namespace Oqtane.Modules.Admin.Files
|
||||
@inherits ModuleBase
|
||||
@inject IFolderService FolderService
|
||||
@inject IFileService FileService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@if (_folders != null)
|
||||
@ -45,7 +46,7 @@
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
@if (!_isSystem && PageState.QueryString.ContainsKey("id"))
|
||||
{
|
||||
<button type="button" class="btn btn-danger" @onclick="DeleteFolder">Delete</button>
|
||||
<ActionDialog Header="Delete Folder" Message="@("Are You Sure You Wish To Delete This Folder?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFolder())" />
|
||||
}
|
||||
<br />
|
||||
<br />
|
||||
@ -123,7 +124,7 @@
|
||||
AddModuleMessage("Folder Name Not Valid.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
Folder folder;
|
||||
@ -174,7 +175,7 @@
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Saving Folder {FolderId} {Error}", _folderId, ex.Message);
|
||||
AddModuleMessage("Error Saving Module", MessageType.Error);
|
||||
AddModuleMessage("Error Saving Folder", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,9 +183,33 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
await FolderService.DeleteFolderAsync(_folderId);
|
||||
await logger.LogInformation("Folder Deleted {Folder}", _folderId);
|
||||
AddModuleMessage("Folder Deleted", MessageType.Success);
|
||||
bool isparent = false;
|
||||
foreach (Folder folder in _folders)
|
||||
{
|
||||
if (folder.ParentId == _folderId)
|
||||
{
|
||||
isparent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isparent)
|
||||
{
|
||||
var files = await FileService.GetFilesAsync(_folderId);
|
||||
if (files.Count == 0)
|
||||
{
|
||||
await FolderService.DeleteFolderAsync(_folderId);
|
||||
await logger.LogInformation("Folder Deleted {Folder}", _folderId);
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("Folder Has Files And Cannot Be Deleted", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("Folder Has Subfolders And Cannot Be Deleted", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -28,6 +28,7 @@
|
||||
</table>
|
||||
<Pager Items="@_files">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Name</th>
|
||||
<th>Modified</th>
|
||||
@ -35,6 +36,7 @@
|
||||
<th>Size</th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td><ActionLink Action="Details" Text="Edit" Parameters="@($"id=" + context.FileId.ToString())" /></td>
|
||||
<td><ActionDialog Header="Delete File" Message="@("Are You Sure You Wish To Delete " + context.Name + "?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFile(context))" /></td>
|
||||
<td><a href="@(ContentUrl(context.FileId))" target="_new">@context.Name</a></td>
|
||||
<td>@context.ModifiedOn</td>
|
||||
|
@ -63,10 +63,18 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="retention-log" HelpText="What items do you want in the retention log">Retention Log (Items): </Label>
|
||||
<Label For="retention" HelpText="Number of log entries to retain for this job">Retention Log (Items): </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="retention-log" class="form-control" @bind="@_retentionHistory" />
|
||||
<input id="retention" class="form-control" @bind="@_retentionHistory" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="next" HelpText="Next execution for this job.">Next Execution: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="next" class="form-control" @bind="@_nextExecution" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -83,6 +91,7 @@
|
||||
private string _startDate = string.Empty;
|
||||
private string _endDate = string.Empty;
|
||||
private string _retentionHistory = string.Empty;
|
||||
private string _nextExecution = string.Empty;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
@ -102,6 +111,7 @@
|
||||
_startDate = (job.StartDate != null) ? job.StartDate.ToString() : string.Empty;
|
||||
_endDate = (job.EndDate != null) ? job.EndDate.ToString() : string.Empty;
|
||||
_retentionHistory = job.RetentionHistory.ToString();
|
||||
_nextExecution = job.NextExecution.ToString();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -140,6 +150,15 @@
|
||||
job.EndDate = DateTime.Parse(_endDate);
|
||||
}
|
||||
|
||||
if (_nextExecution == string.Empty)
|
||||
{
|
||||
job.NextExecution = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
job.NextExecution = DateTime.Parse(_nextExecution);
|
||||
}
|
||||
|
||||
job.RetentionHistory = int.Parse(_retentionHistory);
|
||||
|
||||
try
|
||||
|
@ -22,7 +22,7 @@ else
|
||||
<td>@context.FinishDate</td>
|
||||
</Row>
|
||||
<Detail>
|
||||
<td colspan="4">@context.Notes</td>
|
||||
<td colspan="4">@((MarkupString)context.Notes)</td>
|
||||
</Detail>
|
||||
</Pager>
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
@namespace Oqtane.Modules.Admin.Login
|
||||
@namespace Oqtane.Modules.Admin.Login
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IUserService UserService
|
||||
@ -16,14 +16,14 @@
|
||||
<ModuleMessage Message="You Are Already Logged In" Type="MessageType.Info" />
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<div class="container">
|
||||
<div class="container Oqtane-Modules-Admin-Login">
|
||||
<div class="form-group">
|
||||
<label for="Username" class="control-label">Username: </label>
|
||||
<input type="text" name="Username" class="form-control" placeholder="Username" @bind="@_username" id="Username" />
|
||||
<input type="text" name="Username" class="form-control username" placeholder="Username" @bind="@_username" id="Username" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Password" class="control-label">Password: </label>
|
||||
<input type="password" name="Password" class="form-control" placeholder="Password" @bind="@_password" id="Password" />
|
||||
<input type="password" name="Password" class="form-control password" placeholder="Password" @bind="@_password" id="Password" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-check form-check-inline">
|
||||
@ -49,18 +49,23 @@
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
|
||||
};
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (PageState.QueryString.ContainsKey("returnurl"))
|
||||
{
|
||||
_returnUrl = PageState.QueryString["returnurl"];
|
||||
}
|
||||
|
||||
|
||||
if (PageState.QueryString.ContainsKey("name"))
|
||||
{
|
||||
_username = PageState.QueryString["name"];
|
||||
}
|
||||
|
||||
|
||||
if (PageState.QueryString.ContainsKey("token"))
|
||||
{
|
||||
var user = new User();
|
||||
@ -90,7 +95,7 @@
|
||||
user.Username = _username;
|
||||
user.Password = _password;
|
||||
user = await UserService.LoginUserAsync(user, false, false);
|
||||
|
||||
|
||||
if (user.IsAuthenticated)
|
||||
{
|
||||
await logger.LogInformation("Login Successful For Username {Username}", _username);
|
||||
@ -154,7 +159,7 @@
|
||||
{
|
||||
_message = "Please Enter The Username Related To Your Account And Then Select The Forgot Password Option Again";
|
||||
}
|
||||
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
@ -1,59 +1,76 @@
|
||||
@namespace Oqtane.Modules.Admin.ModuleCreator
|
||||
@namespace Oqtane.Modules.Admin.ModuleCreator
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IModuleDefinitionService ModuleDefinitionService
|
||||
@inject IModuleService ModuleService
|
||||
@inject ISystemService SystemService
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="owner" HelpText="Enter the name of the organization who is developing this module. It should not contain spaces or punctuation.">Owner Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="owner" class="form-control" @bind="@_owner" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="module" HelpText="Enter a name for this module. It should be in singular form (ie. Car) and not contain spaces or punctuation.">Module Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="module" class="form-control" @bind="@_module" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="description" HelpText="Enter s short description for the module">Description: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="3"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="template" HelpText="Select a module template. Internal modules are created inside of the Oqtane solution. External modules are created outside of the Oqtane solution.">Template: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="template" class="form-control" @onchange="(e => TemplateChanged(e))">
|
||||
<option value="-"><Select Template></option>
|
||||
<option value="internal">Internal</option>
|
||||
<option value="external">External</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (!string.IsNullOrEmpty(_location))
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="location" HelpText="Location where the module will be created">Location: </Label>
|
||||
<Label For="owner" HelpText="Enter the name of the organization who is developing this module. It should not contain spaces or punctuation.">Owner Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="module" class="form-control" @bind="@_location" readonly />
|
||||
<input id="owner" class="form-control" @bind="@_owner" />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="module" HelpText="Enter a name for this module. It should not contain spaces or punctuation.">Module Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="module" class="form-control" @bind="@_module" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="description" HelpText="Enter s short description for the module">Description: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="3"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="template" HelpText="Select a module template. Internal modules are created inside of the Oqtane solution. External modules are created outside of the Oqtane solution.">Template: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="template" class="form-control" @onchange="(e => TemplateChanged(e))">
|
||||
<option value="-"><Select Template></option>
|
||||
<option value="internal">Internal</option>
|
||||
<option value="external">External</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="reference" HelpText="Select a framework reference version">Framework Reference: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="reference" class="form-control" @bind="@_reference">
|
||||
@foreach (string version in Constants.ReleaseVersions.Split(','))
|
||||
{
|
||||
if (Version.Parse(version).CompareTo(Version.Parse("2.0.0")) >= 0)
|
||||
{
|
||||
<option value="@(version)">@(version)</option>
|
||||
}
|
||||
}
|
||||
<option value="local">Local Version</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (!string.IsNullOrEmpty(_location))
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="location" HelpText="Location where the module will be created">Location: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="module" class="form-control" @bind="@_location" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
|
||||
<button type="button" class="btn btn-success" @onclick="CreateModule">Create Module</button>
|
||||
|
||||
@ -62,13 +79,14 @@
|
||||
private string _module = string.Empty;
|
||||
private string _description = string.Empty;
|
||||
private string _template = "-";
|
||||
public string _reference = Constants.Version;
|
||||
private string _location = string.Empty;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
AddModuleMessage("Please Note That Once You Select The Create Module Button The Application Must Restart In Order To Complete The Process. If You Create An External Module You Will Need To Compile The Source Code In Order To Make It Functional.", MessageType.Info);
|
||||
AddModuleMessage("Please Note That Once You Select The Create Module Button The Application Must Restart In Order To Complete The Process. If You Create An External Module You Will Need To Compile The Source Code And Then Relaunch Your Site In Order To Make It Functional.", MessageType.Info);
|
||||
}
|
||||
|
||||
private async Task CreateModule()
|
||||
@ -77,7 +95,11 @@
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_owner) && !string.IsNullOrEmpty(_module) && _template != "-")
|
||||
{
|
||||
var moduleDefinition = new ModuleDefinition { Owner = _owner.Replace(" ", ""), Name = _module.Replace(" ", ""), Description = _description, Template = _template };
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 5);
|
||||
|
||||
var moduleDefinition = new ModuleDefinition { Owner = _owner.Replace(" ", ""), Name = _module.Replace(" ", ""), Description = _description, Template = _template, Version = _reference };
|
||||
await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition, ModuleState.ModuleId);
|
||||
}
|
||||
else
|
||||
@ -105,11 +127,11 @@
|
||||
string[] path = systeminfo["serverpath"].Split('\\');
|
||||
if (_template == "internal")
|
||||
{
|
||||
_location = string.Join("\\", path, 0, path.Length - 1) + "\\Oqtane.Client\\Modules\\" + _owner + "." + _module + "s";
|
||||
_location = string.Join("\\", path, 0, path.Length - 1) + "\\Oqtane.Client\\Modules\\" + _owner + "." + _module;
|
||||
}
|
||||
else
|
||||
{
|
||||
_location = string.Join("\\", path, 0, path.Length - 2) + "\\" + _owner + "." + _module + "s";
|
||||
_location = string.Join("\\", path, 0, path.Length - 2) + "\\" + _owner + "." + _module;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -75,12 +75,20 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="license" HelpText="The license of the module">License: </Label>
|
||||
<Label For="license" HelpText="The module license terms">License: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="runtimes" HelpText="The Blazor runtimes which this module supports">Runtimes: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="runtimes" class="form-control" @bind="@_runtimes" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</Section>
|
||||
</TabPanel>
|
||||
@ -110,6 +118,7 @@
|
||||
private string _url = "";
|
||||
private string _contact = "";
|
||||
private string _license = "";
|
||||
private string _runtimes = "";
|
||||
private string _permissions;
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
@ -139,6 +148,7 @@
|
||||
_url = moduleDefinition.Url;
|
||||
_contact = moduleDefinition.Contact;
|
||||
_license = moduleDefinition.License;
|
||||
_runtimes = moduleDefinition.Runtimes;
|
||||
_permissions = moduleDefinition.Permissions;
|
||||
_createdby = moduleDefinition.CreatedBy;
|
||||
_createdon = moduleDefinition.CreatedOn;
|
||||
|
@ -86,7 +86,7 @@ else
|
||||
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", moduledefinitionname, version);
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -102,7 +102,7 @@ else
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -31,9 +31,15 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content);
|
||||
StateHasChanged();
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
bool success = await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content);
|
||||
if (success)
|
||||
{
|
||||
AddModuleMessage("Content Imported Successfully", MessageType.Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("A Problem Was Encountered Importing Content. Please Ensure The Content Is Formatted Correctly For The Module.", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -162,17 +162,6 @@
|
||||
<input id="Icon" class="form-control" @bind="@_icon" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Default-Mode" HelpText="Select the default administration mode you want for this page">Default Mode? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Default-Mode" class="form-control" @bind="@_mode">
|
||||
<option value="view">View Mode</option>
|
||||
<option value="edit">Edit Mode</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
|
||||
@ -217,7 +206,6 @@
|
||||
private string _isnavigation = "True";
|
||||
private string _url;
|
||||
private string _ispersonalizable = "False";
|
||||
private string _mode = "view";
|
||||
private string _themetype = "-";
|
||||
private string _layouttype = "-";
|
||||
private string _containertype = "-";
|
||||
@ -311,7 +299,7 @@
|
||||
Page page = null;
|
||||
try
|
||||
{
|
||||
if (_name != string.Empty && !string.IsNullOrEmpty(_themetype) && (_layouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)))
|
||||
if (_name != string.Empty && !string.IsNullOrEmpty(_themetype) && (_layouts.Count == 0 || _layouttype != "-"))
|
||||
{
|
||||
page = new Page();
|
||||
page.SiteId = PageState.Page.SiteId;
|
||||
@ -346,6 +334,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (!PagePathIsUnique(page.Path, page.SiteId, _pageList))
|
||||
{
|
||||
AddModuleMessage($"A page with path {_path} already exists for the selected parent page. The page path needs to be unique for the selected parent.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
Page child;
|
||||
switch (_insert)
|
||||
{
|
||||
@ -367,7 +361,6 @@
|
||||
|
||||
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
|
||||
page.Url = _url;
|
||||
page.EditMode = (_mode == "edit" ? true : false);
|
||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
@ -396,7 +389,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide Page Name And Theme", MessageType.Warning);
|
||||
AddModuleMessage("You Must Provide Page Name And Theme/Layout", MessageType.Warning);
|
||||
}
|
||||
|
||||
}
|
||||
@ -407,4 +400,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
private static bool PagePathIsUnique(string pagePath, int siteId, List<Page> existingPages)
|
||||
{
|
||||
return !existingPages.Any(page => page.SiteId == siteId && page.Path == pagePath);
|
||||
}
|
||||
}
|
||||
|
@ -173,17 +173,6 @@
|
||||
<input id="Icon" class="form-control" @bind="@_icon" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Default-Mode" HelpText="Select the default administration mode you want for this page">Default Mode? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Default-Mode" class="form-control" @bind="@_mode">
|
||||
<option value="view">View Mode</option>
|
||||
<option value="edit">Edit Mode</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
|
||||
@ -235,7 +224,6 @@
|
||||
private string _isnavigation;
|
||||
private string _url;
|
||||
private string _ispersonalizable;
|
||||
private string _mode;
|
||||
private string _themetype = "-";
|
||||
private string _layouttype = "-";
|
||||
private string _containertype = "-";
|
||||
@ -290,7 +278,6 @@
|
||||
_isnavigation = page.IsNavigation.ToString();
|
||||
_url = page.Url;
|
||||
_ispersonalizable = page.IsPersonalizable.ToString();
|
||||
_mode = (page.EditMode) ? "edit" : "view";
|
||||
_themetype = page.ThemeType;
|
||||
if (_themetype == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
@ -333,7 +320,7 @@
|
||||
_children = new List<Page>();
|
||||
if (_parentid == "-1")
|
||||
{
|
||||
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))
|
||||
{
|
||||
@ -433,6 +420,13 @@
|
||||
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PagePathIsUnique(page.Path, page.SiteId, page.PageId, _pageList))
|
||||
{
|
||||
AddModuleMessage($"A page with path {_path} already exists for the selected parent page. The page path needs to be unique for the selected parent.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_insert != "=")
|
||||
{
|
||||
Page child;
|
||||
@ -456,7 +450,6 @@
|
||||
}
|
||||
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
|
||||
page.Url = _url;
|
||||
page.EditMode = (_mode == "edit");
|
||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
@ -512,4 +505,9 @@
|
||||
AddModuleMessage("Error Saving Page", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool PagePathIsUnique(string pagePath, int siteId, int pageId, List<Page> existingPages)
|
||||
{
|
||||
return !existingPages.Any(page => page.SiteId == siteId && page.Path == pagePath && page.PageId != pageId);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
@namespace Oqtane.Modules.Admin.Profiles
|
||||
@namespace Oqtane.Modules.Admin.Profiles
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IProfileService ProfileService
|
||||
@ -6,7 +6,7 @@
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="name" HelpText="The name of this field">Name: </Label>
|
||||
<Label For="name" HelpText="The name of this profile item">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
@ -14,7 +14,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="title" HelpText="The title of the field">Title: </Label>
|
||||
<Label For="title" HelpText="The title of the profile item to display to the user">Title: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="title" class="form-control" @bind="@_title" />
|
||||
@ -22,7 +22,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="description" HelpText="What the profile field is">Description: </Label>
|
||||
<Label For="description" HelpText="The help text displayed to the user for this profile item">Description: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea>
|
||||
@ -30,7 +30,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="category" HelpText="What larger category does this field belong to">Category: </Label>
|
||||
<Label For="category" HelpText="The category of this profile item (for grouping)">Category: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="category" class="form-control" @bind="@_category" />
|
||||
@ -38,7 +38,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="order" HelpText="What place is this field in a larger category list">Order: </Label>
|
||||
<Label For="order" HelpText="The index order of where this profile item should be displayed">Order: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="order" class="form-control" @bind="@_vieworder" />
|
||||
@ -46,7 +46,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="length" HelpText="What is the max amount of characters should this field accept">Length: </Label>
|
||||
<Label For="length" HelpText="The max number of characters this profile item should accept (enter zero for unlimited)">Length: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="length" class="form-control" @bind="@_maxlength" />
|
||||
@ -54,7 +54,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultVal" HelpText="What value do you want this field to start with">Default Value: </Label>
|
||||
<Label For="defaultVal" HelpText="The default value for this profile item">Default Value: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="defaultVal" class="form-control" @bind="@_defaultvalue" />
|
||||
@ -62,7 +62,15 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="required" HelpText="Is a user required to input something into this field?">Required? </Label>
|
||||
<Label For="options" HelpText="A comma delimited list of options the user can select from">Options: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="options" class="form-control" @bind="@_options" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="required" HelpText="Should a user be required to provide a value for this profile item?">Required? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="required" class="form-control" @bind="@_isrequired">
|
||||
@ -73,7 +81,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="private" HelpText="Is this field private?">Private? </Label>
|
||||
<Label For="private" HelpText="Should this profile item be visible to all users?">Private? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="private" class="form-control" @bind="@_isprivate">
|
||||
@ -95,6 +103,7 @@
|
||||
private string _vieworder = "0";
|
||||
private string _maxlength = "0";
|
||||
private string _defaultvalue = string.Empty;
|
||||
private string _options = string.Empty;
|
||||
private string _isrequired = "False";
|
||||
private string _isprivate = "False";
|
||||
|
||||
@ -119,6 +128,7 @@
|
||||
_vieworder = profile.ViewOrder.ToString();
|
||||
_maxlength = profile.MaxLength.ToString();
|
||||
_defaultvalue = profile.DefaultValue;
|
||||
_options = profile.Options;
|
||||
_isrequired = profile.IsRequired.ToString();
|
||||
_isprivate = profile.IsPrivate.ToString();
|
||||
}
|
||||
@ -145,6 +155,7 @@
|
||||
profile = new Profile();
|
||||
}
|
||||
|
||||
profile.SiteId = PageState.Site.SiteId;
|
||||
profile.Name = _name;
|
||||
profile.Title = _title;
|
||||
profile.Description = _description;
|
||||
@ -152,6 +163,7 @@
|
||||
profile.ViewOrder = int.Parse(_vieworder);
|
||||
profile.MaxLength = int.Parse(_maxlength);
|
||||
profile.DefaultValue = _defaultvalue;
|
||||
profile.Options = _options;
|
||||
profile.IsRequired = (_isrequired == null ? false : Boolean.Parse(_isrequired));
|
||||
profile.IsPrivate = (_isprivate == null ? false : Boolean.Parse(_isprivate));
|
||||
if (_profileid != -1)
|
||||
|
@ -88,7 +88,7 @@ else
|
||||
Role role = await RoleService.GetRoleAsync(roleid);
|
||||
name = role.Name;
|
||||
users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId);
|
||||
users = users.Where(item => item.Role.Name == Constants.RegisteredRole).ToList();
|
||||
users = users.Where(item => item.Role.Name == RoleNames.Registered).ToList();
|
||||
await GetUserRoles();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -7,7 +7,7 @@
|
||||
@inject IThemeService ThemeService
|
||||
@inject ISettingService SettingService
|
||||
|
||||
@if (_themes != null)
|
||||
@if (_initialized)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
@ -211,6 +211,7 @@
|
||||
}
|
||||
|
||||
@code {
|
||||
private bool _initialized = false;
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||
@ -318,6 +319,8 @@
|
||||
_deletedby = site.DeletedBy;
|
||||
_deletedon = site.DeletedOn;
|
||||
_isdeleted = site.IsDeleted.ToString();
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -445,7 +448,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide A Site Name, Alias, And Default Theme/Container", MessageType.Warning);
|
||||
AddModuleMessage("You Must Provide A Site Name, Alias, And Default Theme/Layout/Container", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -216,7 +216,7 @@ else
|
||||
private string _username = string.Empty;
|
||||
private string _password = string.Empty;
|
||||
private bool _integratedsecurity = true;
|
||||
private string _hostusername = Constants.HostUser;
|
||||
private string _hostusername = UserNames.Host;
|
||||
private string _hostpassword = string.Empty;
|
||||
|
||||
private string _name = string.Empty;
|
||||
@ -311,7 +311,7 @@ else
|
||||
// validate host credentials
|
||||
var user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = Constants.HostUser;
|
||||
user.Username = UserNames.Host;
|
||||
user.Password = _hostpassword;
|
||||
user = await UserService.LoginUserAsync(user, false, false);
|
||||
if (user.IsAuthenticated)
|
||||
@ -402,7 +402,7 @@ else
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide A Tenant, Site Name, Alias, Default Theme/Container, And Site Template", MessageType.Warning);
|
||||
AddModuleMessage("You Must Provide A Tenant, Site Name, Alias, Default Theme/Layout/Container, And Site Template", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
@inject IAliasService AliasService
|
||||
@inject IThemeService ThemeService
|
||||
|
||||
@if (_themes != null)
|
||||
@if (_initialized)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
@ -106,6 +106,7 @@
|
||||
}
|
||||
|
||||
@code {
|
||||
private bool _initialized = false;
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||
@ -163,6 +164,8 @@
|
||||
_deletedby = site.DeletedBy;
|
||||
_deletedon = site.DeletedOn;
|
||||
_isdeleted = site.IsDeleted.ToString();
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -9,7 +9,7 @@
|
||||
<Label For="name" HelpText="The name of the tenant">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
@if (name == Constants.MasterTenant)
|
||||
@if (name == TenantNames.Master)
|
||||
{
|
||||
<input id="name" class="form-control" @bind="@name" readonly />
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ else
|
||||
</Header>
|
||||
<Row>
|
||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.TenantId.ToString())" /></td>
|
||||
<td><ActionDialog Header="Delete Tenant" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Tenant?")" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteTenant(context))" Disabled="@(context.Name == Constants.MasterTenant)" /></td>
|
||||
<td><ActionDialog Header="Delete Tenant" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Tenant?")" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteTenant(context))" Disabled="@(context.Name == TenantNames.Master)" /></td>
|
||||
<td>@context.Name</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
|
@ -79,7 +79,7 @@
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await ThemeService.InstallThemesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -87,7 +87,7 @@ else
|
||||
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version);
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await ThemeService.InstallThemesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -103,7 +103,7 @@ else
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await ThemeService.DeleteThemeAsync(Theme.ThemeName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -12,7 +12,7 @@
|
||||
@if (_upgradeavailable)
|
||||
{
|
||||
<ModuleMessage Type="MessageType.Info" Message="Select The Upgrade Button To Install a New Framework Version"></ModuleMessage>
|
||||
@("Framework") @_package.Version <button type="button" class="btn btn-success" @onclick=@(async () => await Download(Constants.PackageId, Constants.Version))>Upgrade</button>
|
||||
<button type="button" class="btn btn-success" @onclick=@(async () => await Download(Constants.PackageId, @_package.Version))>Upgrade To @_package.Version</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -26,7 +26,7 @@
|
||||
<Label HelpText="Upload a framework package and select Install to complete the installation">Framework: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<FileManager Filter="nupkg" Folder="Framework" />
|
||||
<FileManager Filter="nupkg" ShowFiles="false" Folder="Framework" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -71,7 +71,7 @@
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await InstallationService.Upgrade();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -88,7 +88,7 @@
|
||||
await PackageService.DownloadPackageAsync(packageid, version, "Framework");
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await InstallationService.Upgrade();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -1,4 +1,4 @@
|
||||
@namespace Oqtane.Modules.Admin.UserProfile
|
||||
@namespace Oqtane.Modules.Admin.UserProfile
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IUserService UserService
|
||||
@ -75,10 +75,12 @@ else
|
||||
<TabPanel Name="Profile">
|
||||
@if (profiles != null && settings != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
@foreach (Profile profile in profiles)
|
||||
<table class="table table-borderless">
|
||||
@foreach (Profile profile in profiles)
|
||||
{
|
||||
var p = profile;
|
||||
if (!p.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||
{
|
||||
var p = profile;
|
||||
if (p.Category != category)
|
||||
{
|
||||
<tr>
|
||||
@ -90,14 +92,41 @@ else
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<label for="@p.Name" class="control-label">@p.Title: </label>
|
||||
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" placeholder="@p.Description" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
@if (!string.IsNullOrEmpty(p.Options))
|
||||
{
|
||||
<select id="@p.Name" class="form-control" @onchange="@(e => ProfileChanged(e, p.Name))">
|
||||
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
@if(GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
|
||||
{
|
||||
<option value="@option" selected>@option</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@option">@option</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (p.IsRequired)
|
||||
{
|
||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
}
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
}
|
||||
</table>
|
||||
<button type="button" class="btn btn-primary" @onclick="Save">Save</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">Cancel</button>
|
||||
}
|
||||
@ -241,7 +270,7 @@ else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (username != string.Empty && email != string.Empty)
|
||||
if (username != string.Empty && email != string.Empty && ValidateProfiles())
|
||||
{
|
||||
if (password == confirm)
|
||||
{
|
||||
@ -261,6 +290,7 @@ else
|
||||
await UserService.UpdateUserAsync(user);
|
||||
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
||||
await logger.LogInformation("User Profile Saved");
|
||||
AddModuleMessage("User Profile Updated Successfully", MessageType.Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -269,7 +299,7 @@ else
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide A Username and Email Address", MessageType.Warning);
|
||||
AddModuleMessage("You Must Provide A Username and Email Address As Well As All Required Profile Information", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -279,6 +309,26 @@ else
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidateProfiles()
|
||||
{
|
||||
bool valid = true;
|
||||
foreach (Profile profile in profiles)
|
||||
{
|
||||
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||
{
|
||||
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
||||
}
|
||||
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||
{
|
||||
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
private void Cancel()
|
||||
{
|
||||
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
|
||||
|
@ -71,10 +71,17 @@
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<label for="@p.Name" class="control-label">@p.Title: </label>
|
||||
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" maxlength="@p.MaxLength" placeholder="@p.Description" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
@if (p.IsRequired)
|
||||
{
|
||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@ -112,11 +119,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
private string GetProfileValue(string SettingName, string DefaultValue)
|
||||
=> SettingService.GetSetting(settings, SettingName, DefaultValue);
|
||||
|
||||
private async Task SaveUser()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (username != string.Empty && password != string.Empty && confirm != string.Empty && email != string.Empty)
|
||||
if (username != string.Empty && password != string.Empty && confirm != string.Empty && email != string.Empty && ValidateProfiles())
|
||||
{
|
||||
if (password == confirm)
|
||||
{
|
||||
@ -149,7 +159,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide A Username, Password, and Email Address", MessageType.Warning);
|
||||
AddModuleMessage("You Must Provide A Username, Password, Email Address And All Required Profile Information", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -159,6 +169,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidateProfiles()
|
||||
{
|
||||
bool valid = true;
|
||||
foreach (Profile profile in profiles)
|
||||
{
|
||||
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||
{
|
||||
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
||||
}
|
||||
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||
{
|
||||
var value = (string)e.Value;
|
||||
|
@ -98,10 +98,17 @@ else
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<label for="@p.Name" class="control-label">@p.Title: </label>
|
||||
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" placeholder="@p.Description" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
@if (p.IsRequired)
|
||||
{
|
||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@ -180,7 +187,7 @@ else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (username != string.Empty && email != string.Empty)
|
||||
if (username != string.Empty && email != string.Empty && ValidateProfiles())
|
||||
{
|
||||
if (password == confirm)
|
||||
{
|
||||
@ -213,7 +220,7 @@ else
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide A Username, Password, and Email Address", MessageType.Warning);
|
||||
AddModuleMessage("You Must Provide A Username, Password, Email Address, And All Required Profile Information", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -223,6 +230,23 @@ else
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidateProfiles()
|
||||
{
|
||||
bool valid = true;
|
||||
foreach (Profile profile in profiles)
|
||||
{
|
||||
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||
{
|
||||
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
||||
}
|
||||
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||
{
|
||||
var value = (string)e.Value;
|
||||
|
@ -58,10 +58,10 @@ else
|
||||
{
|
||||
if (string.IsNullOrEmpty(_search))
|
||||
{
|
||||
return allroles.Where(item => item.Role.Name == Constants.RegisteredRole).ToList();
|
||||
return allroles.Where(item => item.Role.Name == RoleNames.Registered).ToList();
|
||||
}
|
||||
return allroles
|
||||
.Where(item => item.Role.Name == Constants.RegisteredRole &&
|
||||
.Where(item => item.Role.Name == RoleNames.Registered &&
|
||||
(
|
||||
item.User.Username.Contains(search, StringComparison.OrdinalIgnoreCase) ||
|
||||
item.User.Email.Contains(search, StringComparison.OrdinalIgnoreCase) ||
|
||||
|
@ -63,7 +63,7 @@ else
|
||||
<Row>
|
||||
<td>@context.Role.Name</td>
|
||||
<td>
|
||||
@if (context.Role.Name != Constants.RegisteredRole)
|
||||
@if (context.Role.Name != RoleNames.Registered)
|
||||
{
|
||||
<button type="button" class="btn btn-danger" @onclick=@(async () => await DeleteUserRole(context.UserRoleId))>Delete</button>
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits LocalizableComponent
|
||||
|
||||
@if (_visible)
|
||||
{
|
||||
<div class="app-admin-modal">
|
||||
<div class="app-actiondialog">
|
||||
<div class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
@ -17,9 +17,9 @@
|
||||
<div class="modal-footer">
|
||||
@if (!string.IsNullOrEmpty(Action))
|
||||
{
|
||||
<button type="button" class="@Class" @onclick="Confirm">@((MarkupString)_iconSpan) @Action</button>
|
||||
<button type="button" class="@Class" @onclick="Confirm">@((MarkupString)_iconSpan) @Localize(Action)</button>
|
||||
}
|
||||
<button type="button" class="btn btn-secondary" @onclick="DisplayModal">Cancel</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="DisplayModal">@Localize("Cancel")</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -40,7 +40,7 @@
|
||||
|
||||
@code {
|
||||
private bool _visible = false;
|
||||
private bool _editmode = true;
|
||||
private bool _editmode = false;
|
||||
private bool _authorized = false;
|
||||
private string _iconSpan = string.Empty;
|
||||
|
||||
@ -66,7 +66,7 @@
|
||||
public bool Disabled { get; set; } // optional
|
||||
|
||||
[Parameter]
|
||||
public string EditMode { get; set; } // optional - specifies if a user must be in edit mode to see the action - default is true
|
||||
public string EditMode { get; set; } // optional - specifies if an authorized user must be in edit mode to see the action - default is false
|
||||
|
||||
[Parameter]
|
||||
public Action OnClick { get; set; } // required if an Action is specified - executes a method in the calling component
|
||||
@ -76,6 +76,8 @@
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
base.OnParametersSet();
|
||||
|
||||
if (string.IsNullOrEmpty(Text))
|
||||
{
|
||||
Text = Action;
|
||||
@ -84,6 +86,7 @@
|
||||
{
|
||||
Class = "btn btn-success";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(EditMode))
|
||||
{
|
||||
_editmode = bool.Parse(EditMode);
|
||||
@ -94,6 +97,12 @@
|
||||
_iconSpan = $"<span class=\"oi oi-{IconName}\"></span> ";
|
||||
}
|
||||
|
||||
if (IsLocalizable)
|
||||
{
|
||||
Header = Localize(nameof(Header));
|
||||
Message = Localize(nameof(Message));
|
||||
}
|
||||
|
||||
_authorized = IsAuthorized();
|
||||
}
|
||||
|
||||
@ -133,10 +142,10 @@
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions);
|
||||
break;
|
||||
case SecurityAccessLevel.Admin:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, Constants.AdminRole);
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin);
|
||||
break;
|
||||
case SecurityAccessLevel.Host:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, Constants.HostRole);
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Host);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits LocalizableComponent
|
||||
@inject IUserService UserService
|
||||
|
||||
@if (_authorized)
|
||||
@ -21,7 +20,7 @@
|
||||
private string _parameters = string.Empty;
|
||||
private string _classname = "btn btn-primary";
|
||||
private string _style = string.Empty;
|
||||
private bool _editmode = true;
|
||||
private bool _editmode = false;
|
||||
private bool _authorized = false;
|
||||
private string _iconSpan = string.Empty;
|
||||
|
||||
@ -47,16 +46,18 @@
|
||||
public bool Disabled { get; set; } // optional
|
||||
|
||||
[Parameter]
|
||||
public string EditMode { get; set; } // optional - specifies if a user must be in edit mode to see the action - default is true
|
||||
public string EditMode { get; set; } // optional - specifies if an authorized user must be in edit mode to see the action - default is false.
|
||||
|
||||
[Parameter]
|
||||
public string IconName { get; set; } // optional - specifies an icon for the link - default is no icon
|
||||
|
||||
|
||||
[Parameter]
|
||||
public bool IconOnly { get; set; } // optional - specifies only icon in link
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
base.OnParametersSet();
|
||||
|
||||
_text = Action;
|
||||
if (!string.IsNullOrEmpty(Text))
|
||||
{
|
||||
@ -90,8 +91,13 @@
|
||||
|
||||
if (!string.IsNullOrEmpty(IconName))
|
||||
{
|
||||
_iconSpan = $"<span class=\"oi oi-{IconName}\"></span>{(IconOnly?"":" ")}";
|
||||
|
||||
_iconSpan = $"<span class=\"oi oi-{IconName}\"></span>{(IconOnly ? "" : " ")}";
|
||||
|
||||
}
|
||||
|
||||
if (IsLocalizable)
|
||||
{
|
||||
_text = Localize(nameof(Text));
|
||||
}
|
||||
|
||||
_url = EditUrl(Action, _parameters);
|
||||
@ -123,7 +129,7 @@
|
||||
{
|
||||
security = Security.Value;
|
||||
}
|
||||
|
||||
|
||||
switch (security)
|
||||
{
|
||||
case SecurityAccessLevel.Anonymous:
|
||||
@ -136,14 +142,14 @@
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.Permissions);
|
||||
break;
|
||||
case SecurityAccessLevel.Admin:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, Constants.AdminRole);
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin);
|
||||
break;
|
||||
case SecurityAccessLevel.Host:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, Constants.HostRole);
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Host);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return authorized;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleControlBase
|
||||
|
||||
@if (_text != string.Empty)
|
||||
{
|
||||
@ -8,21 +7,21 @@
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
|
||||
private string _text = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string CreatedBy { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public DateTime? CreatedOn { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string ModifiedBy { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public DateTime ModifiedOn { get; set; }
|
||||
|
||||
public DateTime? ModifiedOn { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string DeletedBy { get; set; }
|
||||
|
||||
@ -38,54 +37,54 @@
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
_text = string.Empty;
|
||||
if (!String.IsNullOrEmpty(CreatedBy) || CreatedOn != null)
|
||||
if (!String.IsNullOrEmpty(CreatedBy) || CreatedOn.HasValue)
|
||||
{
|
||||
_text += "<p style=\"" + Style + "\">Created ";
|
||||
|
||||
|
||||
if (!String.IsNullOrEmpty(CreatedBy))
|
||||
{
|
||||
_text += " by <b>" + CreatedBy + "</b>";
|
||||
}
|
||||
|
||||
|
||||
if (CreatedOn != null)
|
||||
{
|
||||
_text += " on <b>" + CreatedOn.ToString("MMM dd yyyy HH:mm:ss") + "</b>";
|
||||
_text += " on <b>" + CreatedOn.Value.ToString("MMM dd yyyy HH:mm:ss") + "</b>";
|
||||
}
|
||||
|
||||
|
||||
_text += "</p>";
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(ModifiedBy) || ModifiedOn != null)
|
||||
if (!String.IsNullOrEmpty(ModifiedBy) || ModifiedOn.HasValue)
|
||||
{
|
||||
_text += "<p style=\"" + Style + "\">Last modified ";
|
||||
|
||||
|
||||
if (!String.IsNullOrEmpty(ModifiedBy))
|
||||
{
|
||||
_text += " by <b>" + ModifiedBy + "</b>";
|
||||
}
|
||||
|
||||
|
||||
if (ModifiedOn != null)
|
||||
{
|
||||
_text += " on <b>" + ModifiedOn.ToString("MMM dd yyyy HH:mm:ss") + "</b>";
|
||||
_text += " on <b>" + ModifiedOn.Value.ToString("MMM dd yyyy HH:mm:ss") + "</b>";
|
||||
}
|
||||
|
||||
|
||||
_text += "</p>";
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(DeletedBy) || DeletedOn.HasValue)
|
||||
{
|
||||
_text += "<p style=\"" + Style + "\">Deleted ";
|
||||
|
||||
|
||||
if (!String.IsNullOrEmpty(DeletedBy))
|
||||
{
|
||||
_text += " by <b>" + DeletedBy + "</b>";
|
||||
}
|
||||
|
||||
|
||||
if (DeletedOn != null)
|
||||
{
|
||||
_text += " on <b>" + DeletedOn.Value.ToString("MMM dd yyyy HH:mm:ss") + "</b>";
|
||||
}
|
||||
|
||||
|
||||
_text += "</p>";
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
@inject IFolderService FolderService
|
||||
@inject IFileService FileService
|
||||
|
||||
@ -56,23 +54,23 @@
|
||||
<div>
|
||||
@if (UploadMultiple)
|
||||
{
|
||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter" multiple/>
|
||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter" multiple />
|
||||
}
|
||||
else
|
||||
{
|
||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter"/>
|
||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter" />
|
||||
}
|
||||
<span id="@_progressinfoid"></span><progress id="@_progressbarid" style="width: 150px; visibility: hidden;"></progress>
|
||||
<span class="float-right">
|
||||
<button type="button" class="btn btn-success" @onclick="UploadFile">Upload</button>
|
||||
@if (_showfiles && GetFileId() != -1)
|
||||
@if (ShowFiles && GetFileId() != -1)
|
||||
{
|
||||
<button type="button" class="btn btn-danger" @onclick="DeleteFile">Delete</button>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
@((MarkupString) _message)
|
||||
<ModuleMessage Message="@_message" Type="@_messagetype"></ModuleMessage>
|
||||
</div>
|
||||
@if (_image != string.Empty)
|
||||
{
|
||||
@ -88,15 +86,15 @@
|
||||
private string _id;
|
||||
private List<Folder> _folders;
|
||||
private List<File> _files = new List<File>();
|
||||
private bool _showfiles = true;
|
||||
private string _fileinputid = string.Empty;
|
||||
private string _progressinfoid = string.Empty;
|
||||
private string _progressbarid = string.Empty;
|
||||
private string _filter = "*";
|
||||
private bool _haseditpermission = false;
|
||||
private string _message = string.Empty;
|
||||
private string _image = string.Empty;
|
||||
private string _guid;
|
||||
private string _message = string.Empty;
|
||||
private MessageType _messagetype;
|
||||
|
||||
[Parameter]
|
||||
public string Id { get; set; } // optional - for setting the id of the FileManager component for accessibility
|
||||
@ -134,7 +132,7 @@
|
||||
|
||||
if (!string.IsNullOrEmpty(Folder))
|
||||
{
|
||||
_folders = new List<Folder> {new Folder {FolderId = -1, Name = Folder}};
|
||||
_folders = new List<Folder> { new Folder { FolderId = -1, Name = Folder } };
|
||||
FolderId = -1;
|
||||
}
|
||||
else
|
||||
@ -163,7 +161,7 @@
|
||||
|
||||
await GetFiles();
|
||||
|
||||
// create unique id for component
|
||||
// create unique id for component
|
||||
_guid = Guid.NewGuid().ToString("N");
|
||||
_fileinputid = _guid + "FileInput";
|
||||
_progressinfoid = _guid + "ProgressInfo";
|
||||
@ -175,7 +173,7 @@
|
||||
_haseditpermission = false;
|
||||
if (!string.IsNullOrEmpty(Folder))
|
||||
{
|
||||
_haseditpermission = UserSecurity.IsAuthorized(PageState.User, Constants.HostRole);
|
||||
_haseditpermission = UserSecurity.IsAuthorized(PageState.User, RoleNames.Host);
|
||||
_files = await FileService.GetFilesAsync(Folder);
|
||||
}
|
||||
else
|
||||
@ -211,7 +209,7 @@
|
||||
_message = string.Empty;
|
||||
try
|
||||
{
|
||||
FolderId = int.Parse((string) e.Value);
|
||||
FolderId = int.Parse((string)e.Value);
|
||||
await GetFiles();
|
||||
FileId = -1;
|
||||
_image = string.Empty;
|
||||
@ -220,14 +218,16 @@
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Files {Error}", ex.Message);
|
||||
_message = "<br /><div class=\"alert alert-danger\" role=\"alert\">Error Loading Files</div>";
|
||||
|
||||
_message = "Error Loading Files";
|
||||
_messagetype = MessageType.Error;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task FileChanged(ChangeEventArgs e)
|
||||
{
|
||||
_message = string.Empty;
|
||||
FileId = int.Parse((string) e.Value);
|
||||
FileId = int.Parse((string)e.Value);
|
||||
|
||||
await SetImage();
|
||||
StateHasChanged();
|
||||
@ -244,8 +244,8 @@
|
||||
var maxwidth = 200;
|
||||
var maxheight = 200;
|
||||
|
||||
var ratioX = (double) maxwidth / (double) file.ImageWidth;
|
||||
var ratioY = (double) maxheight / (double) file.ImageHeight;
|
||||
var ratioX = (double)maxwidth / (double)file.ImageWidth;
|
||||
var ratioY = (double)maxheight / (double)file.ImageHeight;
|
||||
var ratio = ratioX < ratioY ? ratioX : ratioY;
|
||||
|
||||
_image = "<img src=\"" + ContentUrl(FileId) + "\" alt=\"" + file.Name +
|
||||
@ -257,6 +257,7 @@
|
||||
|
||||
private async Task UploadFile()
|
||||
{
|
||||
_message = string.Empty;
|
||||
var interop = new Interop(JSRuntime);
|
||||
var upload = await interop.GetFiles(_fileinputid);
|
||||
if (upload.Length > 0)
|
||||
@ -276,7 +277,10 @@
|
||||
if (result == string.Empty)
|
||||
{
|
||||
await logger.LogInformation("File Upload Succeeded {Files}", upload);
|
||||
_message = "<br /><div class=\"alert alert-success\" role=\"alert\">File Upload Succeeded</div>";
|
||||
|
||||
_message = "File Upload Succeeded";
|
||||
_messagetype = MessageType.Success;
|
||||
|
||||
await GetFiles();
|
||||
|
||||
if (upload.Length == 1)
|
||||
@ -293,30 +297,37 @@
|
||||
else
|
||||
{
|
||||
await logger.LogError("File Upload Failed For {Files}", result.Replace(",", ", "));
|
||||
_message = "<br /><div class=\"alert alert-danger\" role=\"alert\">File Upload Failed</div>";
|
||||
|
||||
_message = "File Upload Failed";
|
||||
_messagetype = MessageType.Error;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "File Upload Failed {Error}", ex.Message);
|
||||
_message = "<br /><div class=\"alert alert-danger\" role=\"alert\">File Upload Failed</div>";
|
||||
|
||||
_message = "File Upload Failed";
|
||||
_messagetype = MessageType.Error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_message = "<br /><div class=\"alert alert-warning\" role=\"alert\">You Have Not Selected A File To Upload</div>";
|
||||
_message = "You Have Not Selected A File To Upload";
|
||||
_messagetype = MessageType.Warning;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteFile()
|
||||
{
|
||||
_message = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
await FileService.DeleteFileAsync(FileId);
|
||||
await logger.LogInformation("File Deleted {File}", FileId);
|
||||
_message = "<br /><div class=\"alert alert-success\" role=\"alert\">File Deleted</div>";
|
||||
|
||||
_message = "File Deleted";
|
||||
_messagetype = MessageType.Success;
|
||||
|
||||
await GetFiles();
|
||||
FileId = -1;
|
||||
await SetImage();
|
||||
@ -325,7 +336,9 @@
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting File {File} {Error}", FileId, ex.Message);
|
||||
_message = "<br /><div class=\"alert alert-danger\" role=\"alert\">Error Deleting File</div>";
|
||||
|
||||
_message = "Error Deleting File";
|
||||
_messagetype = MessageType.Error;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits LocalizableComponent
|
||||
|
||||
@if (!string.IsNullOrEmpty(HelpText))
|
||||
{
|
||||
@ -16,7 +15,7 @@ else
|
||||
private string _closeLabel = "</label>";
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string For { get; set; } // optional - the id of the associated input control for accessibility
|
||||
@ -29,17 +28,25 @@ else
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
base.OnParametersSet();
|
||||
|
||||
_openLabel = "<label";
|
||||
if (!string.IsNullOrEmpty(For))
|
||||
{
|
||||
_openLabel += " for=\"" + For + "\"";
|
||||
}
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(Class))
|
||||
{
|
||||
_openLabel += " class=\"" + Class + "\"";
|
||||
}
|
||||
|
||||
|
||||
_openLabel += ">";
|
||||
|
||||
if (IsLocalizable)
|
||||
{
|
||||
ChildContent =@<text>@Localize("Text")</text>;
|
||||
HelpText = Localize(nameof(HelpText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
56
Oqtane.Client/Modules/Controls/LocalizableComponent.cs
Normal file
56
Oqtane.Client/Modules/Controls/LocalizableComponent.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Modules.Controls
|
||||
{
|
||||
public class LocalizableComponent : ModuleControlBase
|
||||
{
|
||||
private IStringLocalizer _localizer;
|
||||
|
||||
[Parameter]
|
||||
public string ResourceKey { get; set; }
|
||||
|
||||
protected bool IsLocalizable { get; private set; }
|
||||
|
||||
protected string Localize(string name)
|
||||
{
|
||||
var key = $"{ResourceKey}.{name}";
|
||||
|
||||
// TODO: we should have a ShowMissingResourceKeys option which developers/translators can enable to find missing translations which would display the key rather than the name
|
||||
if (!IsLocalizable)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
return _localizer?[key] ?? name;
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (!String.IsNullOrEmpty(ResourceKey))
|
||||
{
|
||||
if (ModuleState?.ModuleType != null)
|
||||
{
|
||||
var moduleType = Type.GetType(ModuleState.ModuleType);
|
||||
if (moduleType != null)
|
||||
{
|
||||
using (var scope = ServiceActivator.GetScope())
|
||||
{
|
||||
var localizerFactory = scope.ServiceProvider.GetService<IStringLocalizerFactory>();
|
||||
_localizer = localizerFactory.Create(moduleType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IsLocalizable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsLocalizable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +1,22 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleControlBase
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@if (!string.IsNullOrEmpty(_message))
|
||||
{
|
||||
<div class="@_classname" role="alert">@_message</div>
|
||||
<div class="@_classname" role="alert">
|
||||
@_message
|
||||
@if (Type == MessageType.Error && PageState != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
@((MarkupString)" ")<NavLink href="@NavigateUrl("admin/log")">View Details</NavLink>
|
||||
}
|
||||
</div>
|
||||
<br />
|
||||
}
|
||||
|
||||
@code {
|
||||
private string _message = string.Empty;
|
||||
private string _classname = "alert alert-danger";
|
||||
private string _classname = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string Message { get; set; }
|
||||
@ -20,23 +26,16 @@
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Message))
|
||||
_message = Message;
|
||||
if (!string.IsNullOrEmpty(_message))
|
||||
{
|
||||
_message = Message;
|
||||
_classname = GetMessageType(Type);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetModuleMessage(string message, MessageType type)
|
||||
{
|
||||
_message = message;
|
||||
_classname = GetMessageType(type);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private string GetMessageType(MessageType type)
|
||||
{
|
||||
var classname = string.Empty;
|
||||
string classname = string.Empty;
|
||||
switch (type)
|
||||
{
|
||||
case MessageType.Success:
|
||||
@ -52,7 +51,7 @@
|
||||
classname = "alert alert-danger";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return classname;
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +1,39 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@typeparam TableItem
|
||||
|
||||
@inherits ModuleControlBase
|
||||
@typeparam TableItem
|
||||
|
||||
<p>
|
||||
@if(Format == "Table")
|
||||
@if (Format == "Table")
|
||||
{
|
||||
<table class="@Class">
|
||||
<thead>
|
||||
<tr>@Header</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<table class="@Class">
|
||||
<thead>
|
||||
<tr>@Header</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ItemList)
|
||||
{
|
||||
<tr>@Row(item)</tr>
|
||||
@if (Detail != null)
|
||||
{
|
||||
<tr>@Detail(item)</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
@if (Format == "Grid")
|
||||
{
|
||||
<div class="@Class">
|
||||
<div class="row">@Header</div>
|
||||
@foreach (var item in ItemList)
|
||||
{
|
||||
<tr>@Row(item)</tr>
|
||||
<div class="row">@Row(item)</div>
|
||||
@if (Detail != null)
|
||||
{
|
||||
<tr>@Detail(item)</tr>
|
||||
<div class="row">@Detail(item)</div>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
@if(Format == "Grid")
|
||||
{
|
||||
<div class="@Class">
|
||||
<div class="row">@Header</div>
|
||||
@foreach (var item in ItemList)
|
||||
{
|
||||
<div class="row">@Row(item)</div>
|
||||
@if (Detail != null)
|
||||
{
|
||||
<div class="row">@Detail(item)</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="mx-auto text-center">
|
||||
@if (_page > _maxPages)
|
||||
@ -44,7 +42,7 @@
|
||||
}
|
||||
@if (_endPage > 1)
|
||||
{
|
||||
<button class="btn btn-secondary" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></button>
|
||||
<button class="btn btn-secondary" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></button>
|
||||
@for (int i = _startPage; i <= _endPage; i++)
|
||||
{
|
||||
var pager = i;
|
||||
@ -105,7 +103,7 @@
|
||||
{
|
||||
Format = "Table";
|
||||
}
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(Class))
|
||||
{
|
||||
if (Format == "Table")
|
||||
@ -117,7 +115,7 @@
|
||||
Class = "container";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(PageSize))
|
||||
{
|
||||
_maxItems = 10;
|
||||
@ -126,7 +124,7 @@
|
||||
{
|
||||
_maxItems = int.Parse(PageSize);
|
||||
}
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(DisplayPages))
|
||||
{
|
||||
_maxPages = 5;
|
||||
@ -149,7 +147,7 @@
|
||||
{
|
||||
ItemList = Items.Skip((currentPage - 1) * _maxItems).Take(_maxItems);
|
||||
_page = currentPage;
|
||||
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
@ -174,7 +172,7 @@
|
||||
{
|
||||
_endPage = _pages;
|
||||
}
|
||||
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
else if (direction == "back")
|
||||
@ -208,7 +206,7 @@
|
||||
_page -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UpdateList(_page);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
@inject IRoleService RoleService
|
||||
@inject IUserService UserService
|
||||
|
||||
@ -39,7 +38,7 @@
|
||||
<th scope="col">User</th>
|
||||
@foreach (PermissionString permission in _permissions)
|
||||
{
|
||||
<th style="text-align: center; width: 1px;">@permission.PermissionName</th>
|
||||
<th style="text-align: center; width: 1px;">@permission.PermissionName</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
@ -48,7 +47,7 @@
|
||||
{
|
||||
string userid = "[" + user.UserId.ToString() + "]";
|
||||
<tr>
|
||||
<td >@user.DisplayName</td>
|
||||
<td>@user.DisplayName</td>
|
||||
@foreach (PermissionString permission in _permissions)
|
||||
{
|
||||
var p = permission;
|
||||
@ -104,16 +103,16 @@
|
||||
}
|
||||
|
||||
_roles = await RoleService.GetRolesAsync(ModuleState.SiteId);
|
||||
_roles.Insert(0, new Role { Name = Constants.AllUsersRole });
|
||||
_roles.Insert(0, new Role { Name = RoleNames.Everyone });
|
||||
|
||||
_permissions = new List<PermissionString>();
|
||||
|
||||
|
||||
foreach (string permissionname in _permissionnames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
// initialize with admin role
|
||||
_permissions.Add(new PermissionString { PermissionName = permissionname, Permissions = Constants.AdminRole });
|
||||
_permissions.Add(new PermissionString { PermissionName = permissionname, Permissions = RoleNames.Admin });
|
||||
}
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(Permissions))
|
||||
{
|
||||
// populate permissions
|
||||
@ -123,7 +122,7 @@
|
||||
{
|
||||
_permissions[_permissions.FindIndex(item => item.PermissionName == permissionstring.PermissionName)].Permissions = permissionstring.Permissions;
|
||||
}
|
||||
|
||||
|
||||
if (permissionstring.Permissions.Contains("["))
|
||||
{
|
||||
foreach (string user in permissionstring.Permissions.Split(new char[] { '[' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
@ -162,7 +161,7 @@
|
||||
}
|
||||
|
||||
private bool GetPermissionDisabled(string roleName)
|
||||
=> roleName == Constants.AdminRole
|
||||
=> roleName == RoleNames.Admin
|
||||
? true
|
||||
: false;
|
||||
|
||||
@ -183,7 +182,7 @@
|
||||
_message = "Username Does Not Exist";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_username = string.Empty;
|
||||
}
|
||||
|
||||
@ -209,7 +208,7 @@
|
||||
case null:
|
||||
break; // permission not specified
|
||||
}
|
||||
|
||||
|
||||
_permissions[_permissions.FindIndex(item => item.PermissionName == permissionName)].Permissions = string.Join(";", ids.ToArray());
|
||||
}
|
||||
}
|
||||
@ -227,8 +226,8 @@
|
||||
{
|
||||
permission = _permissions[i];
|
||||
List<string> ids = permission.Permissions.Split(';').ToList();
|
||||
ids.Remove("!" + Constants.AllUsersRole); // remove deny all users
|
||||
ids.Remove("!" + Constants.RegisteredRole); // remove deny registered users
|
||||
ids.Remove("!" + RoleNames.Everyone); // remove deny all users
|
||||
ids.Remove("!" + RoleNames.Registered); // remove deny registered users
|
||||
permission.Permissions = string.Join(";", ids.ToArray());
|
||||
_permissions[i] = permission;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
|
||||
<div class="row" style="margin-bottom: 50px;">
|
||||
<div class="col">
|
||||
@ -9,7 +8,7 @@
|
||||
@if (_filemanagervisible)
|
||||
{
|
||||
<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
|
||||
@((MarkupString)_message)
|
||||
<ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage>
|
||||
<br />
|
||||
}
|
||||
<div class="row justify-content-center" style="margin-bottom: 20px;">
|
||||
@ -113,7 +112,7 @@
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-blot-formatter.min.js" },
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-interop.js" }
|
||||
};
|
||||
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_content = Content; // raw HTML
|
||||
@ -182,6 +181,7 @@
|
||||
|
||||
public async Task InsertImage()
|
||||
{
|
||||
_message = string.Empty;
|
||||
if (_filemanagervisible)
|
||||
{
|
||||
var fileid = _fileManager.GetFileId();
|
||||
@ -190,17 +190,15 @@
|
||||
var interop = new RichTextEditorInterop(JSRuntime);
|
||||
await interop.InsertImage(_editorElement, ContentUrl(fileid));
|
||||
_filemanagervisible = false;
|
||||
_message = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
_message = "<br /><div class=\"alert alert-warning\" role=\"alert\">You Must Select An Image To Insert</div>";
|
||||
_message = "You Must Select An Image To Insert";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_filemanagervisible = true;
|
||||
_message = string.Empty;
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits LocalizableComponent
|
||||
|
||||
<div class="d-flex">
|
||||
<div>
|
||||
@ -42,4 +41,16 @@
|
||||
_heading = (!string.IsNullOrEmpty(Heading)) ? Heading : Name;
|
||||
_expanded = (!string.IsNullOrEmpty(Expanded)) ? Expanded : "false";
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
base.OnParametersSet();
|
||||
|
||||
if (IsLocalizable)
|
||||
{
|
||||
_heading = !string.IsNullOrEmpty(Heading)
|
||||
? Localize(nameof(Heading))
|
||||
: Localize(nameof(Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits LocalizableComponent
|
||||
|
||||
@if (Name == Parent.ActiveTab)
|
||||
{
|
||||
@ -28,9 +27,34 @@ else
|
||||
[Parameter]
|
||||
public string Heading { get; set; } // optional - defaults to name if not specified
|
||||
|
||||
[Parameter]
|
||||
public SecurityAccessLevel? Security { get; set; } // optional - can be used to specify SecurityAccessLevel
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
Parent.AddTabPanel((TabPanel)this);
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
base.OnParametersSet();
|
||||
|
||||
if (IsLocalizable)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Heading))
|
||||
{
|
||||
Name = Localize(nameof(Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
Heading = Localize(nameof(Heading));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayHeading()
|
||||
{
|
||||
return (string.IsNullOrEmpty(Heading)) ? Name : Heading;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleControlBase
|
||||
|
||||
<CascadingValue Value="this">
|
||||
<div class="container-fluid">
|
||||
@ -8,20 +7,23 @@
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
@foreach (TabPanel tabPanel in _tabPanels)
|
||||
{
|
||||
<li class="nav-item">
|
||||
@if (tabPanel.Name == ActiveTab)
|
||||
{
|
||||
<a class="nav-link active" data-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
|
||||
@DisplayHeading(tabPanel.Name, tabPanel.Heading)
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="nav-link" data-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
|
||||
@DisplayHeading(tabPanel.Name, tabPanel.Heading)
|
||||
</a>
|
||||
}
|
||||
</li>
|
||||
@if (IsAuthorized(tabPanel))
|
||||
{
|
||||
<li class="nav-item">
|
||||
@if (tabPanel.Name == ActiveTab)
|
||||
{
|
||||
<a class="nav-link active" data-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
|
||||
@tabPanel.DisplayHeading()
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="nav-link" data-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
|
||||
@tabPanel.DisplayHeading()
|
||||
</a>
|
||||
}
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
@ -59,8 +61,30 @@
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private string DisplayHeading(string Name, string Heading)
|
||||
private bool IsAuthorized(TabPanel tabPanel)
|
||||
{
|
||||
return (string.IsNullOrEmpty(Heading)) ? Name : Heading;
|
||||
var authorized = false;
|
||||
switch (tabPanel.Security)
|
||||
{
|
||||
case null: // security not specified - assume SecurityAccessLevel.Anonymous
|
||||
authorized = true;
|
||||
break;
|
||||
case SecurityAccessLevel.Anonymous:
|
||||
authorized = true;
|
||||
break;
|
||||
case SecurityAccessLevel.View:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, ModuleState.Permissions);
|
||||
break;
|
||||
case SecurityAccessLevel.Edit:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.Permissions);
|
||||
break;
|
||||
case SecurityAccessLevel.Admin:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin);
|
||||
break;
|
||||
case SecurityAccessLevel.Host:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Host);
|
||||
break;
|
||||
}
|
||||
return authorized;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleControlBase
|
||||
|
||||
<img src="@_src" title="@_title" @onclick="SetValue" />
|
||||
|
||||
@ -38,7 +39,7 @@
|
||||
_value = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
SetImage();
|
||||
OnChange(_value);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
@if (PageState.EditMode)
|
||||
{
|
||||
<br /><ActionLink Action="Edit" /><br /><br />
|
||||
<br /><ActionLink Action="Edit" EditMode="true" /><br /><br />
|
||||
}
|
||||
|
||||
@code {
|
||||
|
@ -21,23 +21,23 @@ namespace Oqtane.Modules.HtmlText.Services
|
||||
|
||||
public async Task<HtmlTextInfo> GetHtmlTextAsync(int moduleId)
|
||||
{
|
||||
var htmltext = await GetJsonAsync<List<HtmlTextInfo>>($"{ApiUrl}/{moduleId}?entityid={moduleId}");
|
||||
var htmltext = await GetJsonAsync<List<HtmlTextInfo>>(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", moduleId));
|
||||
return htmltext.FirstOrDefault();
|
||||
}
|
||||
|
||||
public async Task AddHtmlTextAsync(HtmlTextInfo htmlText)
|
||||
{
|
||||
await PostJsonAsync($"{ApiUrl}?entityid={htmlText.ModuleId}", htmlText);
|
||||
await PostJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}", htmlText.ModuleId), htmlText);
|
||||
}
|
||||
|
||||
public async Task UpdateHtmlTextAsync(HtmlTextInfo htmlText)
|
||||
{
|
||||
await PutJsonAsync($"{ApiUrl}/{htmlText.HtmlTextId}?entityid={htmlText.ModuleId}", htmlText);
|
||||
await PutJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{htmlText.HtmlTextId}", htmlText.ModuleId), htmlText);
|
||||
}
|
||||
|
||||
public async Task DeleteHtmlTextAsync(int moduleId)
|
||||
{
|
||||
await DeleteAsync($"{ApiUrl}/{moduleId}?entityid={moduleId}");
|
||||
await DeleteAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", moduleId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
Success,
|
||||
Info,
|
||||
Warning,
|
||||
Error
|
||||
Error,
|
||||
Undefined
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.Models;
|
||||
using System.Threading.Tasks;
|
||||
@ -17,7 +17,7 @@ namespace Oqtane.Modules
|
||||
private Logger _logger;
|
||||
|
||||
protected Logger logger => _logger ?? (_logger = new Logger(this));
|
||||
|
||||
|
||||
[Inject]
|
||||
protected ILogService LoggingService { get; set; }
|
||||
|
||||
@ -30,7 +30,7 @@ namespace Oqtane.Modules
|
||||
[CascadingParameter]
|
||||
protected Module ModuleState { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
[CascadingParameter]
|
||||
protected ModuleInstance ModuleInstance { get; set; }
|
||||
|
||||
// optional interface properties
|
||||
@ -53,16 +53,19 @@ namespace Oqtane.Modules
|
||||
if (Resources != null && Resources.Exists(item => item.ResourceType == ResourceType.Script))
|
||||
{
|
||||
var scripts = new List<object>();
|
||||
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script))
|
||||
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script && item.Declaration != ResourceDeclaration.Global))
|
||||
{
|
||||
scripts.Add(new { href = resource.Url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "" });
|
||||
}
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.IncludeScripts(scripts.ToArray());
|
||||
if (scripts.Any())
|
||||
{
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.IncludeScripts(scripts.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// path method
|
||||
|
||||
public string ModulePath()
|
||||
@ -116,6 +119,54 @@ namespace Oqtane.Modules
|
||||
return Utilities.ContentUrl(PageState.Alias, fileid);
|
||||
}
|
||||
|
||||
public virtual Dictionary<string, string> GetUrlParameters(string parametersTemplate = "")
|
||||
{
|
||||
var urlParameters = new Dictionary<string, string>();
|
||||
string[] templateSegments;
|
||||
var parameters = PageState.UrlParameters.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||
var parameterId = 0;
|
||||
|
||||
if (string.IsNullOrEmpty(parametersTemplate))
|
||||
{
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
urlParameters.TryAdd("parameter" + i, parameters[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
templateSegments = parametersTemplate.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (parameters.Length == templateSegments.Length)
|
||||
{
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
if (parameters.Length > i)
|
||||
{
|
||||
if (templateSegments[i] == parameters[i])
|
||||
{
|
||||
urlParameters.TryAdd("parameter" + parameterId, parameters[i]);
|
||||
parameterId++;
|
||||
}
|
||||
else if (templateSegments[i].StartsWith("{") && templateSegments[i].EndsWith("}"))
|
||||
{
|
||||
var key = templateSegments[i].Replace("{", "");
|
||||
key = key.Replace("}", "");
|
||||
urlParameters.TryAdd(key, parameters[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = parameters.Length;
|
||||
urlParameters.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return urlParameters;
|
||||
}
|
||||
|
||||
// user feedback methods
|
||||
public void AddModuleMessage(string message, MessageType type)
|
||||
{
|
||||
@ -154,12 +205,15 @@ namespace Oqtane.Modules
|
||||
case "add":
|
||||
logFunction = LogFunction.Create;
|
||||
break;
|
||||
|
||||
case "edit":
|
||||
logFunction = LogFunction.Update;
|
||||
break;
|
||||
|
||||
case "delete":
|
||||
logFunction = LogFunction.Delete;
|
||||
break;
|
||||
|
||||
default:
|
||||
logFunction = LogFunction.Read;
|
||||
break;
|
||||
|
10
Oqtane.Client/Modules/ModuleControlBase.cs
Normal file
10
Oqtane.Client/Modules/ModuleControlBase.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Modules
|
||||
{
|
||||
[OqtaneIgnore]
|
||||
public abstract class ModuleControlBase : ModuleBase
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<RazorLangVersion>3.0</RazorLangVersion>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>1.0.1</Version>
|
||||
<Version>2.0.0</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@ -15,7 +14,7 @@
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/oqtane</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.1</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0</PackageReleaseNotes>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
@ -28,11 +27,11 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.0" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.0" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="3.1.4" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="3.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.0" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="5.0.0" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,19 +1,19 @@
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Threading.Tasks;
|
||||
using Oqtane.Services;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using Oqtane.Modules;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.Providers;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.Loader;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using System.IO.Compression;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Oqtane.Modules;
|
||||
using Oqtane.Providers;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.Services;
|
||||
|
||||
namespace Oqtane.Client
|
||||
{
|
||||
@ -28,6 +28,9 @@ namespace Oqtane.Client
|
||||
builder.Services.AddSingleton(httpClient);
|
||||
builder.Services.AddOptions();
|
||||
|
||||
// Register localization services
|
||||
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
|
||||
|
||||
// register auth services
|
||||
builder.Services.AddAuthorizationCore();
|
||||
builder.Services.AddScoped<IdentityAuthenticationStateProvider>();
|
||||
@ -62,32 +65,33 @@ namespace Oqtane.Client
|
||||
|
||||
await LoadClientAssemblies(httpClient);
|
||||
|
||||
// dynamically register module contexts and repository services
|
||||
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
foreach (Assembly assembly in assemblies)
|
||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
var implementationTypes = assembly.GetTypes()
|
||||
.Where(item => item.GetInterfaces().Contains(typeof(IService)));
|
||||
|
||||
foreach (Type implementationtype in implementationTypes)
|
||||
// dynamically register module services
|
||||
var implementationTypes = assembly.GetInterfaces<IService>();
|
||||
foreach (var implementationType in implementationTypes)
|
||||
{
|
||||
Type servicetype = Type.GetType(implementationtype.AssemblyQualifiedName.Replace(implementationtype.Name, "I" + implementationtype.Name));
|
||||
if (servicetype != null)
|
||||
if (implementationType.AssemblyQualifiedName != null)
|
||||
{
|
||||
builder.Services.AddScoped(servicetype, implementationtype); // traditional service interface
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Services.AddScoped(implementationtype, implementationtype); // no interface defined for service
|
||||
var serviceType = Type.GetType(implementationType.AssemblyQualifiedName.Replace(implementationType.Name, $"I{implementationType.Name}"));
|
||||
builder.Services.AddScoped(serviceType ?? implementationType, implementationType);
|
||||
}
|
||||
}
|
||||
|
||||
assembly.GetInstances<IClientStartup>()
|
||||
.ToList()
|
||||
.ForEach(x => x.ConfigureServices(builder.Services));
|
||||
// register client startup services
|
||||
var startUps = assembly.GetInstances<IClientStartup>();
|
||||
foreach (var startup in startUps)
|
||||
{
|
||||
startup.ConfigureServices(builder.Services);
|
||||
}
|
||||
}
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
var host = builder.Build();
|
||||
|
||||
ServiceActivator.Configure(host.Services);
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
private static async Task LoadClientAssemblies(HttpClient http)
|
||||
@ -101,8 +105,8 @@ namespace Oqtane.Client
|
||||
// asemblies and debug symbols are packaged in a zip file
|
||||
using (ZipArchive archive = new ZipArchive(new MemoryStream(zip)))
|
||||
{
|
||||
Dictionary<string, byte[]> dlls = new Dictionary<string, byte[]>();
|
||||
Dictionary<string, byte[]> pdbs = new Dictionary<string, byte[]>();
|
||||
var dlls = new Dictionary<string, byte[]>();
|
||||
var pdbs = new Dictionary<string, byte[]>();
|
||||
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
{
|
||||
@ -129,11 +133,11 @@ namespace Oqtane.Client
|
||||
{
|
||||
if (pdbs.ContainsKey(item.Key))
|
||||
{
|
||||
Assembly.Load(item.Value, pdbs[item.Key]);
|
||||
AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(item.Value), new MemoryStream(pdbs[item.Key]));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assembly.Load(item.Value);
|
||||
AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(item.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,6 +170,21 @@ namespace Oqtane.Services
|
||||
// can be used to override the default alias
|
||||
public Alias Alias { get; set; }
|
||||
|
||||
// add entityid parameter to url for custom authorization policy
|
||||
public string CreateAuthorizationPolicyUrl(string url, int entityId)
|
||||
{
|
||||
string qs = "entityid=" + entityId.ToString();
|
||||
|
||||
if (url.Contains("?"))
|
||||
{
|
||||
return url + "&" + qs;
|
||||
}
|
||||
else
|
||||
{
|
||||
return url + "?" + qs;
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("This method is obsolete. Use CreateApiUrl(Alias alias, string serviceName) instead.", false)]
|
||||
public string CreateApiUrl(Alias alias, string absoluteUri, string serviceName)
|
||||
{
|
||||
|
@ -23,7 +23,7 @@
|
||||
</div>
|
||||
<div class="@BodyClass">
|
||||
|
||||
@if (UserSecurity.IsAuthorized(PageState.User, Constants.AdminRole))
|
||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@ -51,7 +51,7 @@
|
||||
</div>
|
||||
<br />
|
||||
<div class="row">
|
||||
@if (UserSecurity.GetPermissionStrings(PageState.Page.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(Constants.AllUsersRole))
|
||||
@if (UserSecurity.GetPermissionStrings(PageState.Page.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(RoleNames.Everyone))
|
||||
{
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick=@(async () => Publish("unpublish"))>Unpublish Page</button>
|
||||
@ -127,7 +127,10 @@
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize, moduledefinition.Permissions))
|
||||
{
|
||||
<option value="@moduledefinition.ModuleDefinitionName">@moduledefinition.Name</option>
|
||||
if (moduledefinition.Runtimes == "" || moduledefinition.Runtimes.Contains(PageState.Runtime.ToString()))
|
||||
{
|
||||
<option value="@moduledefinition.ModuleDefinitionName">@moduledefinition.Name</option>
|
||||
}
|
||||
}
|
||||
}
|
||||
</select>
|
||||
@ -196,26 +199,17 @@
|
||||
|
||||
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null))
|
||||
{
|
||||
@if (PageState.Page.EditMode)
|
||||
if (PageState.EditMode)
|
||||
{
|
||||
<button type="button" class="btn @ButtonClass active" aria-pressed="true" autocomplete="off">
|
||||
<button type="button" class="btn @ButtonClass active" data-toggle="button" aria-pressed="true" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
|
||||
<span class="oi oi-pencil"></span>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PageState.EditMode)
|
||||
{
|
||||
<button type="button" class="btn @ButtonClass active" data-toggle="button" aria-pressed="true" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
|
||||
<span class="oi oi-pencil"></span>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button type="button" class="btn @ButtonClass" data-toggle="button" aria-pressed="false" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
|
||||
<span class="oi oi-pencil"></span>
|
||||
</button>
|
||||
}
|
||||
<button type="button" class="btn @ButtonClass" data-toggle="button" aria-pressed="false" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
|
||||
<span class="oi oi-pencil"></span>
|
||||
</button>
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,8 +510,8 @@
|
||||
if (permissionstring.PermissionName == PermissionNames.View)
|
||||
{
|
||||
List<string> ids = permissionstring.Permissions.Split(';').ToList();
|
||||
if (!ids.Contains(Constants.AllUsersRole)) ids.Add(Constants.AllUsersRole);
|
||||
if (!ids.Contains(Constants.RegisteredRole)) ids.Add(Constants.RegisteredRole);
|
||||
if (!ids.Contains(RoleNames.Everyone)) ids.Add(RoleNames.Everyone);
|
||||
if (!ids.Contains(RoleNames.Registered)) ids.Add(RoleNames.Registered);
|
||||
permissionstring.Permissions = string.Join(";", ids.ToArray());
|
||||
}
|
||||
}
|
||||
@ -537,12 +531,12 @@
|
||||
switch (action)
|
||||
{
|
||||
case "publish":
|
||||
if (!ids.Contains(Constants.AllUsersRole)) ids.Add(Constants.AllUsersRole);
|
||||
if (!ids.Contains(Constants.RegisteredRole)) ids.Add(Constants.RegisteredRole);
|
||||
if (!ids.Contains(RoleNames.Everyone)) ids.Add(RoleNames.Everyone);
|
||||
if (!ids.Contains(RoleNames.Registered)) ids.Add(RoleNames.Registered);
|
||||
break;
|
||||
case "unpublish":
|
||||
ids.Remove(Constants.AllUsersRole);
|
||||
ids.Remove(Constants.RegisteredRole);
|
||||
ids.Remove(RoleNames.Everyone);
|
||||
ids.Remove(RoleNames.Registered);
|
||||
break;
|
||||
}
|
||||
permissionstring.Permissions = string.Join(";", ids.ToArray());
|
||||
|
@ -2,7 +2,7 @@
|
||||
@inherits ModuleActionsBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (PageState.EditMode && !PageState.Page.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions))
|
||||
@if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions))
|
||||
{
|
||||
<div class="app-moduleactions">
|
||||
<a class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"></a>
|
||||
@ -15,9 +15,20 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="dropdown-item" @onclick="(async () => await ModuleAction(action))">@action.Name</a>
|
||||
<a class="dropdown-item" @onclick="(async () => await ModuleAction(action))">
|
||||
@if (string.IsNullOrEmpty(action.Icon))
|
||||
{
|
||||
@((MarkupString) " ");
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="oi oi-@action.Icon" aria-hidden="true"></span>
|
||||
}
|
||||
|
||||
@action.Name
|
||||
</a>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace Oqtane.Themes.Controls
|
||||
[Inject] public IPageModuleService PageModuleService { get; set; }
|
||||
[Inject] public IModuleService ModuleService { get; set; }
|
||||
|
||||
protected List<ActionViewModel> Actions;
|
||||
public List<ActionViewModel> Actions;
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
@ -31,51 +31,52 @@ namespace Oqtane.Themes.Controls
|
||||
var actionList = new List<ActionViewModel>();
|
||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.Permissions))
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Manage Settings", Action = async (u, m) => await Settings(u, m)});
|
||||
if (UserSecurity.GetPermissionStrings(ModuleState.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(Constants.AllUsersRole))
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.Cog, Name = "Manage Settings", Action = async (u, m) => await Settings(u, m)});
|
||||
|
||||
if (UserSecurity.GetPermissionStrings(ModuleState.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(RoleNames.Everyone))
|
||||
{
|
||||
actionList.Add(new ActionViewModel { 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) });
|
||||
}
|
||||
else
|
||||
{
|
||||
actionList.Add(new ActionViewModel { Name = "Publish Module", Action = async (s, m) => await Publish(s, m) });
|
||||
actionList.Add(new ActionViewModel {Icon=Icons.CircleCheck, Name = "Publish Module", Action = async (s, m) => await Publish(s, m) });
|
||||
}
|
||||
actionList.Add(new ActionViewModel { 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 != "")
|
||||
{
|
||||
actionList.Add(new ActionViewModel { Name = "" });
|
||||
actionList.Add(new ActionViewModel {Name = "Import Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Import")});
|
||||
actionList.Add(new ActionViewModel {Name = "Export Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Export")});
|
||||
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.CloudDownload, Name = "Export Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Export")});
|
||||
}
|
||||
|
||||
actionList.Add(new ActionViewModel {Name = ""});
|
||||
|
||||
if (ModuleState.PaneModuleIndex > 0)
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Move To Top", Action = async (s, m) => await MoveTop(s, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.DataTransferUpload ,Name = "Move To Top", Action = async (s, m) => await MoveTop(s, m)});
|
||||
}
|
||||
|
||||
if (ModuleState.PaneModuleIndex > 0)
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Move Up", Action = async (s, m) => await MoveUp(s, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.ArrowThickTop, Name = "Move Up", Action = async (s, m) => await MoveUp(s, m)});
|
||||
}
|
||||
|
||||
if (ModuleState.PaneModuleIndex < (ModuleState.PaneModuleCount - 1))
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Move Down", Action = async (s, m) => await MoveDown(s, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.ArrowThickBottom, Name = "Move Down", Action = async (s, m) => await MoveDown(s, m)});
|
||||
}
|
||||
|
||||
if (ModuleState.PaneModuleIndex < (ModuleState.PaneModuleCount - 1))
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Move To Bottom", Action = async (s, m) => await MoveBottom(s, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.DataTransferDownload, Name = "Move To Bottom", Action = async (s, m) => await MoveBottom(s, m)});
|
||||
}
|
||||
|
||||
foreach (string pane in PageState.Page.Panes)
|
||||
{
|
||||
if (pane != ModuleState.Pane)
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Move To " + pane + " Pane", Action = async (s, m) => await MoveToPane(s, pane, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.AccountLogin, Name = "Move To " + pane + " Pane", Action = async (s, m) => await MoveToPane(s, pane, m)});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,8 +141,8 @@ namespace Oqtane.Themes.Controls
|
||||
if (permissionstring.PermissionName == PermissionNames.View)
|
||||
{
|
||||
List<string> ids = permissionstring.Permissions.Split(';').ToList();
|
||||
if (!ids.Contains(Constants.AllUsersRole)) ids.Add(Constants.AllUsersRole);
|
||||
if (!ids.Contains(Constants.RegisteredRole)) ids.Add(Constants.RegisteredRole);
|
||||
if (!ids.Contains(RoleNames.Everyone)) ids.Add(RoleNames.Everyone);
|
||||
if (!ids.Contains(RoleNames.Registered)) ids.Add(RoleNames.Registered);
|
||||
permissionstring.Permissions = string.Join(";", ids.ToArray());
|
||||
}
|
||||
}
|
||||
@ -158,8 +159,8 @@ namespace Oqtane.Themes.Controls
|
||||
if (permissionstring.PermissionName == PermissionNames.View)
|
||||
{
|
||||
List<string> ids = permissionstring.Permissions.Split(';').ToList();
|
||||
ids.Remove(Constants.AllUsersRole);
|
||||
ids.Remove(Constants.RegisteredRole);
|
||||
ids.Remove(RoleNames.Everyone);
|
||||
ids.Remove(RoleNames.Registered);
|
||||
permissionstring.Permissions = string.Join(";", ids.ToArray());
|
||||
}
|
||||
}
|
||||
@ -202,8 +203,8 @@ namespace Oqtane.Themes.Controls
|
||||
|
||||
public class ActionViewModel
|
||||
{
|
||||
public string Icon { get; set; }
|
||||
public string Name { set; get; }
|
||||
|
||||
public Func<string, PageModule, Task<string>> Action { set; get; }
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
@namespace Oqtane.Themes.Controls
|
||||
@namespace Oqtane.Themes.Controls
|
||||
@inherits ContainerBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@ -17,6 +17,13 @@
|
||||
{
|
||||
title = PageState.Action;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ModuleState.ControlTitle))
|
||||
{
|
||||
title = ModuleState.ControlTitle;
|
||||
}
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
@ -32,12 +32,15 @@ namespace Oqtane.Themes
|
||||
if (Resources != null && Resources.Exists(item => item.ResourceType == ResourceType.Script))
|
||||
{
|
||||
var scripts = new List<object>();
|
||||
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script))
|
||||
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script && item.Declaration != ResourceDeclaration.Global))
|
||||
{
|
||||
scripts.Add(new { href = resource.Url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "" });
|
||||
}
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.IncludeScripts(scripts.ToArray());
|
||||
if (scripts.Any())
|
||||
{
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.IncludeScripts(scripts.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
{
|
||||
_moduleState = Module; // passed in from Pane component
|
||||
string container = _moduleState.ContainerType;
|
||||
if (PageState.ModuleId != -1 && PageState.Action != "" && _moduleState.UseAdminContainer)
|
||||
if (PageState.ModuleId != -1 && _moduleState.UseAdminContainer)
|
||||
{
|
||||
container = Constants.DefaultAdminContainer;
|
||||
}
|
||||
|
@ -119,7 +119,7 @@
|
||||
<div class="row">
|
||||
<div class="mx-auto text-center">
|
||||
<button type="button" class="btn btn-success" @onclick="Install">Install Now</button><br /><br />
|
||||
@((MarkupString) _message)
|
||||
<ModuleMessage Message="@_message" Type="MessageType.Error"></ModuleMessage>
|
||||
</div>
|
||||
<div class="app-progress-indicator" style="@_loadingDisplay"></div>
|
||||
</div>
|
||||
@ -129,13 +129,13 @@
|
||||
private string _databaseType = "LocalDB";
|
||||
private string _serverName = "(LocalDb)\\MSSQLLocalDB";
|
||||
private string _databaseName = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm");
|
||||
private string _username = "";
|
||||
private string _password = "";
|
||||
private string _hostUsername = Constants.HostUser;
|
||||
private string _hostPassword = "";
|
||||
private string _confirmPassword = "";
|
||||
private string _hostEmail = "";
|
||||
private string _message = "";
|
||||
private string _username = string.Empty;
|
||||
private string _password = string.Empty;
|
||||
private string _hostUsername = UserNames.Host;
|
||||
private string _hostPassword = string.Empty;
|
||||
private string _confirmPassword = string.Empty;
|
||||
private string _hostEmail = string.Empty;
|
||||
private string _message = string.Empty;
|
||||
private string _integratedSecurityDisplay = "display: none;";
|
||||
private string _loadingDisplay = "display: none;";
|
||||
|
||||
@ -188,8 +188,8 @@
|
||||
Aliases = uri.Authority,
|
||||
HostEmail = _hostEmail,
|
||||
HostPassword = _hostPassword,
|
||||
HostName = Constants.HostUser,
|
||||
TenantName = Constants.MasterTenant,
|
||||
HostName = UserNames.Host,
|
||||
TenantName = TenantNames.Master,
|
||||
IsNewTenant = true,
|
||||
SiteName = Constants.DefaultSite
|
||||
};
|
||||
@ -201,13 +201,13 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
_message = "<div class=\"alert alert-danger\" role=\"alert\">" + installation.Message + "</div>";
|
||||
_message = installation.Message;
|
||||
_loadingDisplay = "display: none;";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_message = "<div class=\"alert alert-danger\" role=\"alert\">Please Enter All Fields And Ensure Passwords Match And Are Greater Than 5 Characters In Length</div>";
|
||||
_message = "Please Enter All Fields And Ensure Passwords Match And Are Greater Than 5 Characters In Length";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
@namespace Oqtane.UI
|
||||
|
||||
<ModuleMessage Message="@_message" Type="MessageType.Error" />
|
||||
<ModuleMessage Message="@_message" Type="@_messagetype" />
|
||||
<CascadingValue Value="this">
|
||||
<ModuleMessage @ref="ModuleMessage" />
|
||||
@DynamicComponent
|
||||
</CascadingValue>
|
||||
@if (_progressindicator)
|
||||
@ -12,6 +11,7 @@
|
||||
|
||||
@code {
|
||||
private string _message;
|
||||
private MessageType _messagetype;
|
||||
private bool _progressindicator = false;
|
||||
|
||||
[CascadingParameter]
|
||||
@ -49,11 +49,13 @@
|
||||
{
|
||||
// module does not exist with typename specified
|
||||
_message = "Module Does Not Have A Component Named " + Utilities.GetTypeNameLastSegment(typename, 0) + ".razor";
|
||||
_messagetype = MessageType.Error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_message = "Something is wrong with moduletype";
|
||||
_messagetype = MessageType.Error;
|
||||
}
|
||||
|
||||
};
|
||||
@ -61,9 +63,10 @@
|
||||
|
||||
public void AddModuleMessage(string message, MessageType type)
|
||||
{
|
||||
_message = message;
|
||||
_messagetype = type;
|
||||
_progressindicator = false;
|
||||
StateHasChanged();
|
||||
ModuleMessage.SetModuleMessage(message, type);
|
||||
}
|
||||
|
||||
public void ShowProgressIndicator()
|
||||
|
@ -14,10 +14,11 @@ namespace Oqtane.UI
|
||||
public List<Module> Modules { get; set; }
|
||||
public Uri Uri { get; set; }
|
||||
public Dictionary<string, string> QueryString { get; set; }
|
||||
public string UrlParameters { get; set; }
|
||||
public int ModuleId { get; set; }
|
||||
public string Action { get; set; }
|
||||
public bool EditMode { get; set; }
|
||||
public DateTime LastSyncDate { get; set; }
|
||||
public Runtime Runtime { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,24 @@
|
||||
@namespace Oqtane.UI
|
||||
@using Microsoft.AspNetCore.Components.Rendering
|
||||
@namespace Oqtane.UI
|
||||
@inject IUserService UserService
|
||||
@inject IModuleService ModuleService
|
||||
@inject IModuleDefinitionService ModuleDefinitionService
|
||||
|
||||
<div class="@_paneadminborder">
|
||||
@if (_panetitle != "")
|
||||
{
|
||||
@if (_useadminborder)
|
||||
{
|
||||
<div class="@_paneadminborder">
|
||||
@((MarkupString)_panetitle)
|
||||
}
|
||||
@DynamicComponent
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
@DynamicComponent
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
private string _paneadminborder = "";
|
||||
private bool _useadminborder = false;
|
||||
private string _paneadminborder = "container";
|
||||
private string _panetitle = "";
|
||||
|
||||
[CascadingParameter]
|
||||
@ -25,8 +31,9 @@
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (PageState.EditMode && !PageState.Page.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions) && Name != Constants.AdminPane)
|
||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && Name != PaneNames.Admin)
|
||||
{
|
||||
_useadminborder = true;
|
||||
_paneadminborder = "app-pane-admin-border";
|
||||
_panetitle = "<div class=\"app-pane-admin-title\">" + Name + " Pane</div>";
|
||||
}
|
||||
@ -38,12 +45,12 @@
|
||||
|
||||
DynamicComponent = builder =>
|
||||
{
|
||||
if (PageState.ModuleId != -1 && PageState.Action != "")
|
||||
if (PageState.ModuleId != -1 && PageState.Action != Constants.DefaultAction)
|
||||
{
|
||||
if (Name.ToLower() == Constants.AdminPane.ToLower())
|
||||
if (Name.ToLower() == PaneNames.Admin.ToLower())
|
||||
{
|
||||
Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
||||
if (module != null)
|
||||
if (module != null && !module.IsDeleted)
|
||||
{
|
||||
var typename = module.ModuleType;
|
||||
// check for core module actions component
|
||||
@ -51,7 +58,7 @@
|
||||
{
|
||||
typename = Constants.DefaultModuleActionsTemplate.Replace(Constants.ActionToken, PageState.Action);
|
||||
}
|
||||
|
||||
|
||||
var moduleType = Type.GetType(typename);
|
||||
if (moduleType != null)
|
||||
{
|
||||
@ -74,24 +81,17 @@
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, module.Permissions);
|
||||
break;
|
||||
case SecurityAccessLevel.Admin:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, Constants.AdminRole);
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin);
|
||||
break;
|
||||
case SecurityAccessLevel.Host:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, Constants.HostRole);
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, RoleNames.Host);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (authorized)
|
||||
{
|
||||
if (!Constants.DefaultModuleActions.Contains(PageState.Action) && module.ControlTitle != "")
|
||||
{
|
||||
module.Title = module.ControlTitle;
|
||||
}
|
||||
|
||||
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
||||
builder.AddAttribute(1, "Module", module);
|
||||
builder.CloseComponent();
|
||||
CreateComponent(builder, module);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -106,14 +106,12 @@
|
||||
if (PageState.ModuleId != -1)
|
||||
{
|
||||
Module 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() && !module.IsDeleted)
|
||||
{
|
||||
// check if user is authorized to view module
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
||||
{
|
||||
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
||||
builder.AddAttribute(1, "Module", module);
|
||||
builder.CloseComponent();
|
||||
CreateComponent(builder, module);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,14 +122,19 @@
|
||||
// check if user is authorized to view module
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
||||
{
|
||||
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
||||
builder.AddAttribute(1, "Module", module);
|
||||
builder.SetKey(module.PageModuleId);
|
||||
builder.CloseComponent();
|
||||
CreateComponent(builder, module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateComponent(RenderTreeBuilder builder, Module module)
|
||||
{
|
||||
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
||||
builder.AddAttribute(1, "Module", module);
|
||||
builder.SetKey(module.PageModuleId);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
@using System.Diagnostics.CodeAnalysis
|
||||
@using System.Diagnostics.CodeAnalysis
|
||||
@using System.Runtime.InteropServices
|
||||
@namespace Oqtane.UI
|
||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||
@ -76,7 +76,8 @@
|
||||
User user = null;
|
||||
List<Module> modules;
|
||||
var moduleid = -1;
|
||||
var action = "";
|
||||
var action = Constants.DefaultAction;
|
||||
var urlparameters = string.Empty;
|
||||
var editmode = false;
|
||||
var reload = Reload.None;
|
||||
var lastsyncdate = DateTime.UtcNow;
|
||||
@ -179,21 +180,55 @@
|
||||
// extract admin route elements from path
|
||||
var segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
int result;
|
||||
// check if path has moduleid and action specification ie. pagename/moduleid/action/
|
||||
if (segments.Length >= 2 && int.TryParse(segments[segments.Length - 2], out result))
|
||||
|
||||
int modIdPos = 0;
|
||||
int actionPos = 0;
|
||||
int urlParametersPos = 0;
|
||||
|
||||
for (int i = 0; i < segments.Length; i++)
|
||||
{
|
||||
action = segments[segments.Length - 1];
|
||||
moduleid = result;
|
||||
path = path.Replace(moduleid.ToString() + "/" + action + "/", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if path has moduleid specification ie. pagename/moduleid/
|
||||
if (segments.Length >= 1 && int.TryParse(segments[segments.Length - 1], out result))
|
||||
|
||||
if (segments[i] == Constants.UrlParametersDelimiter)
|
||||
{
|
||||
moduleid = result;
|
||||
path = path.Replace(moduleid.ToString() + "/", "");
|
||||
urlParametersPos = i + 1;
|
||||
}
|
||||
|
||||
if (i >= urlParametersPos && urlParametersPos != 0)
|
||||
{
|
||||
urlparameters += "/" + segments[i];
|
||||
}
|
||||
|
||||
if (segments[i] == Constants.ModuleDelimiter)
|
||||
{
|
||||
modIdPos = i + 1;
|
||||
actionPos = modIdPos + 1;
|
||||
if (actionPos <= segments.Length - 1)
|
||||
{
|
||||
action = segments[actionPos];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check if path has moduleid and action specification ie. pagename/*/moduleid/action/
|
||||
if (modIdPos > 0)
|
||||
{
|
||||
int.TryParse(segments[modIdPos], out result);
|
||||
moduleid = result;
|
||||
if (actionPos > segments.Length - 1)
|
||||
{
|
||||
path = path.Replace(segments[modIdPos - 1] + "/" + segments[modIdPos] + "/", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
path = path.Replace(segments[modIdPos - 1] + "/" + segments[modIdPos] + "/" + segments[actionPos] + "/", "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (urlParametersPos > 0)
|
||||
{
|
||||
path = path.Replace(segments[urlParametersPos - 1] + urlparameters + "/", "");
|
||||
}
|
||||
|
||||
// remove trailing slash so it can be used as a key for Pages
|
||||
@ -220,17 +255,14 @@
|
||||
{
|
||||
page = pages.Where(item => item.Path == path).FirstOrDefault();
|
||||
reload = Reload.Page;
|
||||
if (page != null)
|
||||
{
|
||||
editmode = page.EditMode;
|
||||
}
|
||||
editmode = false;
|
||||
}
|
||||
|
||||
if (page != null)
|
||||
{
|
||||
if (PageState == null)
|
||||
{
|
||||
editmode = page.EditMode;
|
||||
editmode = false;
|
||||
}
|
||||
|
||||
// check if user is authorized to view page
|
||||
@ -243,15 +275,15 @@
|
||||
reload = Reload.Page;
|
||||
}
|
||||
|
||||
if (PageState == null || reload >= Reload.Page)
|
||||
if (PageState == null || reload >= Reload.Site)
|
||||
{
|
||||
modules = await ModuleService.GetModulesAsync(site.SiteId);
|
||||
(page, modules) = ProcessModules(page, modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType);
|
||||
}
|
||||
else
|
||||
{
|
||||
modules = PageState.Modules;
|
||||
}
|
||||
(page, modules) = ProcessModules(page, modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType);
|
||||
|
||||
_pagestate = new PageState
|
||||
{
|
||||
@ -263,6 +295,7 @@
|
||||
Modules = modules,
|
||||
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
||||
QueryString = querystring,
|
||||
UrlParameters = urlparameters,
|
||||
ModuleId = moduleid,
|
||||
Action = action,
|
||||
EditMode = editmode,
|
||||
@ -352,6 +385,10 @@
|
||||
if (string.IsNullOrEmpty(page.ThemeType))
|
||||
{
|
||||
page.ThemeType = site.DefaultThemeType;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(page.LayoutType))
|
||||
{
|
||||
page.LayoutType = site.DefaultLayoutType;
|
||||
}
|
||||
|
||||
@ -360,6 +397,13 @@
|
||||
|
||||
string panes = "";
|
||||
Type themetype = Type.GetType(page.ThemeType);
|
||||
if (themetype == null)
|
||||
{
|
||||
// fallback
|
||||
page.ThemeType = Constants.DefaultTheme;
|
||||
page.LayoutType = Constants.DefaultLayout;
|
||||
themetype = Type.GetType(Constants.DefaultTheme);
|
||||
}
|
||||
if (themetype != null)
|
||||
{
|
||||
var themeobject = Activator.CreateInstance(themetype) as IThemeControl;
|
||||
@ -398,21 +442,28 @@
|
||||
var paneindex = new Dictionary<string, int>();
|
||||
foreach (Module module in modules)
|
||||
{
|
||||
if (module.PageId == page.PageId || module.ModuleId == moduleid)
|
||||
// initialize module control properties
|
||||
module.SecurityAccessLevel = SecurityAccessLevel.Host;
|
||||
module.ControlTitle = "";
|
||||
module.Actions = "";
|
||||
module.UseAdminContainer = false;
|
||||
module.PaneModuleIndex = -1;
|
||||
module.PaneModuleCount = 0;
|
||||
|
||||
if ((module.PageId == page.PageId || module.ModuleId == moduleid))
|
||||
{
|
||||
var typename = string.Empty;
|
||||
if (module.ModuleDefinition != null)
|
||||
var typename = Constants.ErrorModule;
|
||||
if (module.ModuleDefinition != null && (module.ModuleDefinition.Runtimes == "" || module.ModuleDefinition.Runtimes.Contains(GetRuntime().ToString())))
|
||||
{
|
||||
typename = module.ModuleDefinition.ControlTypeTemplate;
|
||||
}
|
||||
else
|
||||
{
|
||||
typename = Constants.ErrorModule;
|
||||
}
|
||||
|
||||
if (module.ModuleId == moduleid && action != "")
|
||||
{
|
||||
// check if the module defines custom routes
|
||||
// handle default action
|
||||
if (action == Constants.DefaultAction && !string.IsNullOrEmpty(module.ModuleDefinition.DefaultAction))
|
||||
{
|
||||
action = module.ModuleDefinition.DefaultAction;
|
||||
}
|
||||
|
||||
// check if the module defines custom action routes
|
||||
if (module.ModuleDefinition.ControlTypeRoutes != "")
|
||||
{
|
||||
foreach (string route in module.ModuleDefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
@ -423,13 +474,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
module.ModuleType = typename.Replace(Constants.ActionToken, action);
|
||||
}
|
||||
else
|
||||
{
|
||||
module.ModuleType = typename.Replace(Constants.ActionToken, Constants.DefaultAction);
|
||||
}
|
||||
|
||||
module.ModuleType = typename.Replace(Constants.ActionToken, action);
|
||||
|
||||
// get additional metadata from IModuleControl interface
|
||||
typename = module.ModuleType;
|
||||
if (Constants.DefaultModuleActions.Contains(action))
|
||||
@ -462,7 +510,7 @@
|
||||
// ensure module's pane exists in current page and if not, assign it to the Admin pane
|
||||
if (page.Panes == null || page.Panes.FindIndex(item => item.Equals(module.Pane, StringComparison.OrdinalIgnoreCase)) == -1)
|
||||
{
|
||||
module.Pane = Constants.AdminPane;
|
||||
module.Pane = PaneNames.Admin;
|
||||
}
|
||||
|
||||
// calculate module position within pane
|
||||
@ -477,6 +525,7 @@
|
||||
|
||||
module.PaneModuleIndex = paneindex[module.Pane.ToLower()];
|
||||
|
||||
// container fallback
|
||||
if (string.IsNullOrEmpty(module.ContainerType))
|
||||
{
|
||||
module.ContainerType = defaultcontainertype;
|
||||
@ -486,7 +535,10 @@
|
||||
|
||||
foreach (Module module in modules.Where(item => item.PageId == page.PageId))
|
||||
{
|
||||
module.PaneModuleCount = paneindex[module.Pane.ToLower()] + 1;
|
||||
if (paneindex.ContainsKey(module.Pane.ToLower()))
|
||||
{
|
||||
module.PaneModuleCount = paneindex[module.Pane.ToLower()] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (page, modules);
|
||||
@ -512,4 +564,4 @@
|
||||
=> RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"))
|
||||
? Runtime.WebAssembly
|
||||
: Runtime.Server;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
@namespace Oqtane.UI
|
||||
@namespace Oqtane.UI
|
||||
@inject IJSRuntime JsRuntime
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@ -33,11 +33,14 @@
|
||||
// manage stylesheets for this page
|
||||
string batch = DateTime.Now.ToString("yyyyMMddHHmmssfff");
|
||||
var links = new List<object>();
|
||||
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
||||
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet && item.Declaration != ResourceDeclaration.Global))
|
||||
{
|
||||
links.Add(new { id = "app-stylesheet-" + batch + "-" + (links.Count + 1).ToString("00"), rel = "stylesheet", href = resource.Url, type = "text/css", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", key = "" });
|
||||
}
|
||||
await interop.IncludeLinks(links.ToArray());
|
||||
if (links.Any())
|
||||
{
|
||||
await interop.IncludeLinks(links.ToArray());
|
||||
}
|
||||
await interop.RemoveElementsById("app-stylesheet", "", "app-stylesheet-" + batch + "-00");
|
||||
|
||||
// add favicon
|
||||
@ -46,7 +49,7 @@
|
||||
await interop.IncludeLink("app-favicon", "shortcut icon", Utilities.ContentUrl(PageState.Alias, PageState.Site.FaviconFileId.Value), "image/x-icon", "", "", "id");
|
||||
}
|
||||
// add PWA support
|
||||
if (PageState.Site.PwaIsEnabled)
|
||||
if (PageState.Site.PwaIsEnabled && PageState.Site.PwaAppIconFileId != null && PageState.Site.PwaSplashIconFileId != null)
|
||||
{
|
||||
await InitializePwa(interop);
|
||||
}
|
||||
@ -54,11 +57,6 @@
|
||||
DynamicComponent = builder =>
|
||||
{
|
||||
var themeType = Type.GetType(PageState.Page.ThemeType);
|
||||
if (themeType == null)
|
||||
{
|
||||
// fallback
|
||||
themeType = Type.GetType(Constants.DefaultTheme);
|
||||
}
|
||||
builder.OpenComponent(0, themeType);
|
||||
builder.CloseComponent();
|
||||
};
|
||||
@ -84,7 +82,7 @@
|
||||
"\"sizes\": \"512x512\", " +
|
||||
"\"type\": \"image/png\" " +
|
||||
"}] " +
|
||||
"} " +
|
||||
"}; " +
|
||||
"const serialized = JSON.stringify(manifest); " +
|
||||
"const blob = new Blob([serialized], {type: 'application/javascript'}); " +
|
||||
"const url = URL.createObjectURL(blob); " +
|
||||
|
@ -1,7 +1,8 @@
|
||||
@using System
|
||||
@using System
|
||||
@using System.Linq
|
||||
@using System.Collections.Generic
|
||||
@using System.Net.Http
|
||||
@using System.Net.Http.Json
|
||||
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
|
@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Client</id>
|
||||
<version>1.0.1</version>
|
||||
<version>2.0.0</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -13,11 +13,11 @@
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane</tags>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.1</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.dll" target="lib\netstandard2.1" />
|
||||
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.pdb" target="lib\netstandard2.1" />
|
||||
<file src="..\Oqtane.Client\bin\Release\net5.0\Oqtane.Client.dll" target="lib\net5.0" />
|
||||
<file src="..\Oqtane.Client\bin\Release\net5.0\Oqtane.Client.pdb" target="lib\net5.0" />
|
||||
</files>
|
||||
</package>
|
@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Framework</id>
|
||||
<version>1.0.1</version>
|
||||
<version>2.0.0</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -13,16 +13,11 @@
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane framework</tags>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.1</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.dll" target="lib\netcoreapp3.1" />
|
||||
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.pdb" target="lib\netcoreapp3.1" />
|
||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Server.dll" target="lib\netcoreapp3.1" />
|
||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Server.pdb" target="lib\netcoreapp3.1" />
|
||||
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.dll" target="lib\netcoreapp3.1" />
|
||||
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.pdb" target="lib\netcoreapp3.1" />
|
||||
<file src="..\Oqtane.Server\wwwroot\**\*.*" target="wwwroot" />
|
||||
<file src="..\Oqtane.Server\bin\Release\net5.0\publish\*.*" target="lib\net5.0" />
|
||||
<file src="..\Oqtane.Server\bin\Release\net5.0\publish\wwwroot\**\*.*" target="wwwroot" />
|
||||
</files>
|
||||
</package>
|
@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Server</id>
|
||||
<version>1.0.1</version>
|
||||
<version>2.0.0</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -13,11 +13,11 @@
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane</tags>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.1</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Server.dll" target="lib\netcoreapp3.1" />
|
||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Server.pdb" target="lib\netcoreapp3.1" />
|
||||
<file src="..\Oqtane.Server\bin\Release\net5.0\Oqtane.Server.dll" target="lib\net5.0" />
|
||||
<file src="..\Oqtane.Server\bin\Release\net5.0\Oqtane.Server.pdb" target="lib\net5.0" />
|
||||
</files>
|
||||
</package>
|
@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Shared</id>
|
||||
<version>1.0.1</version>
|
||||
<version>2.0.0</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -13,11 +13,11 @@
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane</tags>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.1</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.dll" target="lib\netstandard2.1" />
|
||||
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.pdb" target="lib\netstandard2.1" />
|
||||
<file src="..\Oqtane.Shared\bin\Release\net5.0\Oqtane.Shared.dll" target="lib\net5.0" />
|
||||
<file src="..\Oqtane.Shared\bin\Release\net5.0\Oqtane.Shared.pdb" target="lib\net5.0" />
|
||||
</files>
|
||||
</package>
|
1
Oqtane.Package/install.ps1
Normal file
1
Oqtane.Package/install.ps1
Normal file
@ -0,0 +1 @@
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.0.Install.zip" -Force
|
Binary file not shown.
@ -1,5 +1,18 @@
|
||||
DEL "*.nupkg"
|
||||
del "*.nupkg"
|
||||
dotnet clean -c Release ..\Oqtane.sln
|
||||
dotnet build -c Release ..\Oqtane.sln
|
||||
dotnet pack -o .\ -c Release ..\Oqtane.sln
|
||||
nuget.exe pack Oqtane.Framework.nuspec
|
||||
nuget.exe pack Oqtane.Client.nuspec
|
||||
nuget.exe pack Oqtane.Server.nuspec
|
||||
nuget.exe pack Oqtane.Shared.nuspec
|
||||
del /F/Q/S "..\Oqtane.Server\bin\Release\net5.0\publish" > NUL
|
||||
rmdir /Q/S "..\Oqtane.Server\bin\Release\net5.0\publish"
|
||||
dotnet publish ..\Oqtane.Server\Oqtane.Server.csproj /p:Configuration=Release
|
||||
del "..\Oqtane.Server\bin\Release\net5.0\publish\appsettings.json"
|
||||
ren "..\Oqtane.Server\bin\Release\net5.0\publish\appsettings.release.json" "appsettings.json"
|
||||
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1"
|
||||
del "..\Oqtane.Server\bin\Release\net5.0\publish\appsettings.json"
|
||||
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\upgrade.ps1"
|
||||
del "..\Oqtane.Server\bin\Release\net5.0\publish\Oqtane.Upgrade.*"
|
||||
nuget.exe pack Oqtane.Framework.nuspec
|
||||
|
||||
|
||||
|
1
Oqtane.Package/upgrade.ps1
Normal file
1
Oqtane.Package/upgrade.ps1
Normal file
@ -0,0 +1 @@
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.0.Upgrade.zip" -Force
|
@ -14,7 +14,7 @@ using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class AliasController : Controller
|
||||
{
|
||||
private readonly IAliasRepository _aliases;
|
||||
@ -32,7 +32,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public IEnumerable<Alias> Get()
|
||||
{
|
||||
return _aliases.GetAliases();
|
||||
@ -40,7 +40,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET api/<controller>/5
|
||||
[HttpGet("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public Alias Get(int id)
|
||||
{
|
||||
return _aliases.GetAlias(id);
|
||||
@ -86,7 +86,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public Alias Post([FromBody] Alias alias)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -99,7 +99,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public Alias Put(int id, [FromBody] Alias alias)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -112,7 +112,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
_aliases.DeleteAlias(id);
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@ -22,7 +22,7 @@ using Microsoft.AspNetCore.Routing.Constraints;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class FileController : Controller
|
||||
{
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
@ -58,7 +58,7 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
else
|
||||
{
|
||||
if (User.IsInRole(Constants.HostRole))
|
||||
if (User.IsInRole(RoleNames.Host))
|
||||
{
|
||||
folder = GetFolderPath(folder);
|
||||
if (Directory.Exists(folder))
|
||||
@ -132,11 +132,23 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Models.File Put(int id, [FromBody] Models.File file)
|
||||
{
|
||||
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Folder, file.Folder.FolderId, PermissionNames.Edit))
|
||||
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Folder, file.FolderId, PermissionNames.Edit))
|
||||
{
|
||||
file.Folder = _folders.GetFolder(file.FolderId);
|
||||
Models.File _file = _files.GetFile(id, false);
|
||||
if (_file.Name != file.Name || _file.FolderId != file.FolderId)
|
||||
{
|
||||
string folderpath = GetFolderPath(file.Folder);
|
||||
if (!Directory.Exists(folderpath))
|
||||
{
|
||||
Directory.CreateDirectory(folderpath);
|
||||
}
|
||||
System.IO.File.Move(Path.Combine(GetFolderPath(_file.Folder), _file.Name), Path.Combine(folderpath, file.Name));
|
||||
}
|
||||
file.Extension = Path.GetExtension(file.Name).ToLower().Replace(".", "");
|
||||
file = _files.UpdateFile(file);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "File Updated {File}", file);
|
||||
}
|
||||
@ -152,7 +164,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
Models.File file = _files.GetFile(id);
|
||||
@ -270,7 +282,7 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
else
|
||||
{
|
||||
if (User.IsInRole(Constants.HostRole))
|
||||
if (User.IsInRole(RoleNames.Host))
|
||||
{
|
||||
folderPath = GetFolderPath(folder);
|
||||
}
|
||||
@ -432,8 +444,8 @@ namespace Oqtane.Controllers
|
||||
string filepath = Path.Combine(GetFolderPath(file.Folder), file.Name);
|
||||
if (System.IO.File.Exists(filepath))
|
||||
{
|
||||
byte[] filebytes = System.IO.File.ReadAllBytes(filepath);
|
||||
return File(filebytes, "application/octet-stream", file.Name);
|
||||
var stream = new FileStream(filepath, FileMode.Open);
|
||||
return File(stream, "application/octet-stream", file.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -441,8 +453,8 @@ namespace Oqtane.Controllers
|
||||
HttpContext.Response.StatusCode = 404;
|
||||
if (System.IO.File.Exists(errorpath))
|
||||
{
|
||||
byte[] filebytes = System.IO.File.ReadAllBytes(errorpath);
|
||||
return File(filebytes, "application/octet-stream", file.Name);
|
||||
var stream = new FileStream(errorpath, FileMode.Open);
|
||||
return File(stream, "application/octet-stream", file.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -450,16 +462,16 @@ namespace Oqtane.Controllers
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {FileId}", id);
|
||||
HttpContext.Response.StatusCode = 401;
|
||||
byte[] filebytes = System.IO.File.ReadAllBytes(errorpath);
|
||||
return File(filebytes, "application/octet-stream", file.Name);
|
||||
var stream = new FileStream(errorpath, FileMode.Open);
|
||||
return File(stream, "application/octet-stream", file.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Read, "File Not Found {FileId}", id);
|
||||
HttpContext.Response.StatusCode = 404;
|
||||
byte[] filebytes = System.IO.File.ReadAllBytes(errorpath);
|
||||
return File(filebytes, "application/octet-stream", "error.png");
|
||||
var stream = new FileStream(errorpath, FileMode.Open);
|
||||
return File(stream, "application/octet-stream", file.Name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -483,7 +495,7 @@ namespace Oqtane.Controllers
|
||||
string[] folders = folderpath.Split(separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (string folder in folders)
|
||||
{
|
||||
path = Utilities.PathCombine(path, folder, "\\");
|
||||
path = Utilities.PathCombine(path, folder, Path.DirectorySeparatorChar.ToString());
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Oqtane.Models;
|
||||
@ -10,20 +11,25 @@ using Oqtane.Extensions;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Repository;
|
||||
using Oqtane.Security;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class FolderController : Controller
|
||||
{
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
private readonly IFolderRepository _folders;
|
||||
private readonly IUserPermissions _userPermissions;
|
||||
private readonly ITenantResolver _tenants;
|
||||
private readonly ILogManager _logger;
|
||||
|
||||
public FolderController(IFolderRepository folders, IUserPermissions userPermissions, ILogManager logger)
|
||||
public FolderController(IWebHostEnvironment environment, IFolderRepository folders, IUserPermissions userPermissions, ITenantResolver tenants, ILogManager logger)
|
||||
{
|
||||
_environment = environment;
|
||||
_folders = folders;
|
||||
_userPermissions = userPermissions;
|
||||
_tenants = tenants;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@ -87,7 +93,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Folder Post([FromBody] Folder folder)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -100,7 +106,7 @@ namespace Oqtane.Controllers
|
||||
else
|
||||
{
|
||||
permissions = new List<Permission> {
|
||||
new Permission(PermissionNames.Edit, Constants.AdminRole, true),
|
||||
new Permission(PermissionNames.Edit, RoleNames.Admin, true),
|
||||
}.EncodePermissions();
|
||||
}
|
||||
if (_userPermissions.IsAuthorized(User, PermissionNames.Edit, permissions))
|
||||
@ -112,7 +118,7 @@ namespace Oqtane.Controllers
|
||||
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
||||
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
|
||||
}
|
||||
folder.Path = Utilities.PathCombine(folder.Path, "\\");
|
||||
folder.Path = Utilities.PathCombine(folder.Path, Path.DirectorySeparatorChar.ToString());
|
||||
folder = _folders.AddFolder(folder);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Added {Folder}", folder);
|
||||
}
|
||||
@ -135,19 +141,26 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Folder Put(int id, [FromBody] Folder folder)
|
||||
{
|
||||
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Folder, folder.FolderId, PermissionNames.Edit))
|
||||
{
|
||||
if (folder.IsPathValid())
|
||||
{
|
||||
if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null)
|
||||
if (folder.ParentId != null)
|
||||
{
|
||||
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
||||
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
|
||||
}
|
||||
folder.Path = Utilities.PathCombine(folder.Path, "\\");
|
||||
folder.Path = Utilities.PathCombine(folder.Path, Path.DirectorySeparatorChar.ToString());
|
||||
|
||||
Models.Folder _folder = _folders.GetFolder(id, false);
|
||||
if (_folder.Path != folder.Path && Directory.Exists(GetFolderPath(_folder)))
|
||||
{
|
||||
Directory.Move(GetFolderPath(_folder), GetFolderPath(folder));
|
||||
}
|
||||
|
||||
folder = _folders.UpdateFolder(folder);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Folder Updated {Folder}", folder);
|
||||
}
|
||||
@ -169,7 +182,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/?siteid=x&folderid=y&parentid=z
|
||||
[HttpPut]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public void Put(int siteid, int folderid, int? parentid)
|
||||
{
|
||||
if (_userPermissions.IsAuthorized(User, EntityNames.Folder, folderid, PermissionNames.Edit))
|
||||
@ -196,11 +209,16 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
if (_userPermissions.IsAuthorized(User, EntityNames.Folder, id, PermissionNames.Edit))
|
||||
{
|
||||
Models.Folder _folder = _folders.GetFolder(id, false);
|
||||
if (Directory.Exists(GetFolderPath(_folder)))
|
||||
{
|
||||
Directory.Delete(GetFolderPath(_folder));
|
||||
}
|
||||
_folders.DeleteFolder(id);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Folder Deleted {FolderId}", id);
|
||||
}
|
||||
@ -210,5 +228,10 @@ namespace Oqtane.Controllers
|
||||
HttpContext.Response.StatusCode = 401;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetFolderPath(Folder folder)
|
||||
{
|
||||
return Utilities.PathCombine(_environment.ContentRootPath, "Content", "Tenants", _tenants.GetTenant().TenantId.ToString(), "Sites", folder.SiteId.ToString(), folder.Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,36 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.Infrastructure;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.IO.Compression;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Modules;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.Themes;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class InstallationController : Controller
|
||||
{
|
||||
private readonly IConfigurationRoot _config;
|
||||
private readonly IInstallationManager _installationManager;
|
||||
private readonly IDatabaseManager _databaseManager;
|
||||
private readonly ILocalizationManager _localizationManager;
|
||||
private readonly IMemoryCache _cache;
|
||||
|
||||
public InstallationController(IConfigurationRoot config, IInstallationManager installationManager, IDatabaseManager databaseManager)
|
||||
public InstallationController(IConfigurationRoot config, IInstallationManager installationManager, IDatabaseManager databaseManager, ILocalizationManager localizationManager, IMemoryCache cache)
|
||||
{
|
||||
_config = config;
|
||||
_installationManager = installationManager;
|
||||
_databaseManager = databaseManager;
|
||||
_localizationManager = localizationManager;
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
// POST api/<controller>
|
||||
@ -35,7 +39,7 @@ namespace Oqtane.Controllers
|
||||
{
|
||||
var installation = new Installation {Success = false, Message = ""};
|
||||
|
||||
if (ModelState.IsValid && (User.IsInRole(Constants.HostRole) || string.IsNullOrEmpty(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
|
||||
if (ModelState.IsValid && (User.IsInRole(RoleNames.Host) || string.IsNullOrEmpty(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
|
||||
{
|
||||
installation = _databaseManager.Install(config);
|
||||
}
|
||||
@ -56,7 +60,7 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("upgrade")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public Installation Upgrade()
|
||||
{
|
||||
var installation = new Installation {Success = true, Message = ""};
|
||||
@ -70,63 +74,7 @@ namespace Oqtane.Controllers
|
||||
{
|
||||
if (_config.GetSection("Runtime").Value == "WebAssembly")
|
||||
{
|
||||
// get list of assemblies which should be downloaded to browser
|
||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
|
||||
var list = assemblies.Select(a => a.GetName().Name).ToList();
|
||||
|
||||
// get module and theme dependencies
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IModule))))
|
||||
{
|
||||
var instance = Activator.CreateInstance(type) as IModule;
|
||||
foreach (string name in instance.ModuleDefinition.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (!list.Contains(name)) list.Add(name);
|
||||
}
|
||||
}
|
||||
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(ITheme))))
|
||||
{
|
||||
var instance = Activator.CreateInstance(type) as ITheme;
|
||||
foreach (string name in instance.Theme.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (!list.Contains(name)) list.Add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create zip file containing assemblies and debug symbols
|
||||
string binfolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
byte[] zipfile;
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
|
||||
{
|
||||
ZipArchiveEntry entry;
|
||||
foreach (string file in list)
|
||||
{
|
||||
entry = archive.CreateEntry(file + ".dll");
|
||||
using (var filestream = new FileStream(Path.Combine(binfolder, file + ".dll"), FileMode.Open, FileAccess.Read))
|
||||
using (var entrystream = entry.Open())
|
||||
{
|
||||
filestream.CopyTo(entrystream);
|
||||
}
|
||||
|
||||
// include debug symbols ( we may want to consider restricting this to only host users or when running in debug mode for performance )
|
||||
if (System.IO.File.Exists(Path.Combine(binfolder, file + ".pdb")))
|
||||
{
|
||||
entry = archive.CreateEntry(file + ".pdb");
|
||||
using (var filestream = new FileStream(Path.Combine(binfolder, file + ".pdb"), FileMode.Open, FileAccess.Read))
|
||||
using (var entrystream = entry.Open())
|
||||
{
|
||||
filestream.CopyTo(entrystream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
zipfile = memoryStream.ToArray();
|
||||
}
|
||||
return File(zipfile, "application/octet-stream", "oqtane.zip");
|
||||
return File(GetAssemblies(), System.Net.Mime.MediaTypeNames.Application.Octet, "oqtane.zip");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -134,5 +82,86 @@ namespace Oqtane.Controllers
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] GetAssemblies()
|
||||
{
|
||||
return _cache.GetOrCreate("assemblies", entry =>
|
||||
{
|
||||
// get list of assemblies which should be downloaded to client
|
||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
|
||||
var list = assemblies.Select(a => a.GetName().Name).ToList();
|
||||
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
|
||||
// insert satellite assemblies at beginning of list
|
||||
foreach (var culture in _localizationManager.GetSupportedCultures())
|
||||
{
|
||||
var assembliesFolderPath = Path.Combine(binFolder, culture);
|
||||
if (culture == Constants.DefaultCulture)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Directory.Exists(assembliesFolderPath))
|
||||
{
|
||||
foreach (var resourceFile in Directory.EnumerateFiles(assembliesFolderPath))
|
||||
{
|
||||
list.Insert(0, Path.Combine(culture, Path.GetFileNameWithoutExtension(resourceFile)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"The satellite assemblies folder named '{culture}' is not found.");
|
||||
}
|
||||
}
|
||||
|
||||
// insert module and theme dependencies at beginning of list
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IModule))))
|
||||
{
|
||||
var instance = Activator.CreateInstance(type) as IModule;
|
||||
foreach (string name in instance.ModuleDefinition.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (!list.Contains(name)) list.Insert(0, name);
|
||||
}
|
||||
}
|
||||
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(ITheme))))
|
||||
{
|
||||
var instance = Activator.CreateInstance(type) as ITheme;
|
||||
foreach (string name in instance.Theme.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (!list.Contains(name)) list.Insert(0, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create zip file containing assemblies and debug symbols
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
|
||||
{
|
||||
foreach (string file in list)
|
||||
{
|
||||
using (var filestream = new FileStream(Path.Combine(binFolder, file + ".dll"), FileMode.Open, FileAccess.Read))
|
||||
using (var entrystream = archive.CreateEntry(file + ".dll").Open())
|
||||
{
|
||||
filestream.CopyTo(entrystream);
|
||||
}
|
||||
|
||||
// include debug symbols
|
||||
if (System.IO.File.Exists(Path.Combine(binFolder, file + ".pdb")))
|
||||
{
|
||||
using (var filestream = new FileStream(Path.Combine(binFolder, file + ".pdb"), FileMode.Open, FileAccess.Read))
|
||||
using (var entrystream = archive.CreateEntry(file + ".pdb").Open())
|
||||
{
|
||||
filestream.CopyTo(entrystream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class JobController : Controller
|
||||
{
|
||||
private readonly IJobRepository _jobs;
|
||||
@ -28,7 +28,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public IEnumerable<Job> Get()
|
||||
{
|
||||
return _jobs.GetJobs();
|
||||
@ -36,7 +36,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET api/<controller>/5
|
||||
[HttpGet("{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public Job Get(int id)
|
||||
{
|
||||
return _jobs.GetJob(id);
|
||||
@ -44,7 +44,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public Job Post([FromBody] Job job)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -57,7 +57,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public Job Put(int id, [FromBody] Job job)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -70,7 +70,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
_jobs.DeleteJob(id);
|
||||
@ -79,7 +79,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET api/<controller>/start
|
||||
[HttpGet("start/{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public void Start(int id)
|
||||
{
|
||||
Job job = _jobs.GetJob(id);
|
||||
@ -93,7 +93,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET api/<controller>/stop
|
||||
[HttpGet("stop/{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public void Stop(int id)
|
||||
{
|
||||
Job job = _jobs.GetJob(id);
|
||||
|
@ -9,7 +9,7 @@ using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class JobLogController : Controller
|
||||
{
|
||||
private readonly IJobLogRepository _jobLogs;
|
||||
@ -23,7 +23,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public IEnumerable<JobLog> Get()
|
||||
{
|
||||
return _jobLogs.GetJobLogs();
|
||||
@ -31,7 +31,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET api/<controller>/5
|
||||
[HttpGet("{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public JobLog Get(int id)
|
||||
{
|
||||
return _jobLogs.GetJobLog(id);
|
||||
@ -39,7 +39,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public JobLog Post([FromBody] JobLog jobLog)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -52,7 +52,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public JobLog Put(int id, [FromBody] JobLog jobLog)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -65,7 +65,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
_jobLogs.DeleteJobLog(id);
|
||||
|
@ -9,7 +9,7 @@ using Oqtane.Shared;
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class LogController : Controller
|
||||
{
|
||||
private readonly ILogManager _logger;
|
||||
@ -23,7 +23,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>?siteid=x&level=y&function=z&rows=50
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public IEnumerable<Log> Get(string siteid, string level, string function, string rows)
|
||||
{
|
||||
return _logs.GetLogs(int.Parse(siteid), level, function, int.Parse(rows));
|
||||
@ -31,7 +31,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET api/<controller>/5
|
||||
[HttpGet("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public Log Get(int id)
|
||||
{
|
||||
return _logs.GetLog(id);
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Oqtane.Models;
|
||||
@ -11,23 +11,29 @@ using Oqtane.Security;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class ModuleController : Controller
|
||||
{
|
||||
private readonly IModuleRepository _modules;
|
||||
private readonly IPageModuleRepository _pageModules;
|
||||
private readonly IPageRepository _pages;
|
||||
private readonly IModuleDefinitionRepository _moduleDefinitions;
|
||||
private readonly ISettingRepository _settings;
|
||||
private readonly IUserPermissions _userPermissions;
|
||||
private readonly ITenantResolver _tenants;
|
||||
private readonly ISyncManager _syncManager;
|
||||
private readonly ILogManager _logger;
|
||||
|
||||
public ModuleController(IModuleRepository modules, IPageModuleRepository pageModules, IPageRepository pages, IModuleDefinitionRepository moduleDefinitions, IUserPermissions userPermissions, ILogManager logger)
|
||||
public ModuleController(IModuleRepository modules, IPageModuleRepository pageModules, IPageRepository pages, IModuleDefinitionRepository moduleDefinitions, ISettingRepository settings, IUserPermissions userPermissions, ITenantResolver tenants, ISyncManager syncManager, ILogManager logger)
|
||||
{
|
||||
_modules = modules;
|
||||
_modules = modules;
|
||||
_pageModules = pageModules;
|
||||
_pages = pages;
|
||||
_moduleDefinitions = moduleDefinitions;
|
||||
_settings = settings;
|
||||
_userPermissions = userPermissions;
|
||||
_tenants = tenants;
|
||||
_syncManager = syncManager;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@ -36,6 +42,8 @@ namespace Oqtane.Controllers
|
||||
public IEnumerable<Module> Get(string siteid)
|
||||
{
|
||||
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(int.Parse(siteid)).ToList();
|
||||
List<Setting> settings = _settings.GetSettings(EntityNames.Module).ToList();
|
||||
|
||||
List<Module> modules = new List<Module>();
|
||||
foreach (PageModule pagemodule in _pageModules.GetPageModules(int.Parse(siteid)))
|
||||
{
|
||||
@ -61,6 +69,8 @@ namespace Oqtane.Controllers
|
||||
module.ContainerType = pagemodule.ContainerType;
|
||||
|
||||
module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
||||
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||
|
||||
modules.Add(module);
|
||||
}
|
||||
@ -77,6 +87,9 @@ namespace Oqtane.Controllers
|
||||
{
|
||||
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
|
||||
module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
||||
module.Settings = _settings.GetSettings(EntityNames.Module, id)
|
||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||
|
||||
return module;
|
||||
}
|
||||
else
|
||||
@ -89,12 +102,13 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Module Post([FromBody] Module module)
|
||||
{
|
||||
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Page, module.PageId, PermissionNames.Edit))
|
||||
{
|
||||
module = _modules.AddModule(module);
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, _tenants.GetAlias().SiteId);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Module Added {Module}", module);
|
||||
}
|
||||
else
|
||||
@ -108,7 +122,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Module Put(int id, [FromBody] Module module)
|
||||
{
|
||||
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Module, module.ModuleId, PermissionNames.Edit))
|
||||
@ -122,12 +136,13 @@ namespace Oqtane.Controllers
|
||||
var pages = _pages.GetPages(module.SiteId).ToList();
|
||||
foreach (Page page in pages)
|
||||
{
|
||||
if (page.PageId != pageModule.PageId && !page.EditMode)
|
||||
if (page.PageId != pageModule.PageId && !page.Path.StartsWith("admin/"))
|
||||
{
|
||||
_pageModules.AddPageModule(new PageModule { PageId = page.PageId, ModuleId = pageModule.ModuleId, Title = pageModule.Title, Pane = pageModule.Pane, Order = pageModule.Order, ContainerType = pageModule.ContainerType });
|
||||
}
|
||||
}
|
||||
}
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, _tenants.GetAlias().SiteId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -140,12 +155,13 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
if (_userPermissions.IsAuthorized(User, EntityNames.Module, id, PermissionNames.Edit))
|
||||
{
|
||||
_modules.DeleteModule(id);
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, _tenants.GetAlias().SiteId);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Deleted {ModuleId}", id);
|
||||
}
|
||||
else
|
||||
@ -157,7 +173,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET api/<controller>/export?moduleid=x
|
||||
[HttpGet("export")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public string Export(int moduleid)
|
||||
{
|
||||
string content = "";
|
||||
@ -175,7 +191,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>/import?moduleid=x
|
||||
[HttpPost("import")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public bool Import(int moduleid, [FromBody] string content)
|
||||
{
|
||||
bool success = false;
|
||||
|
21
Oqtane.Server/Controllers/ModuleControllerBase.cs
Normal file
21
Oqtane.Server/Controllers/ModuleControllerBase.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Oqtane.Infrastructure;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
public class ModuleControllerBase : Controller
|
||||
{
|
||||
protected readonly ILogManager _logger;
|
||||
protected int _entityId = -1; // passed as a querystring parameter for policy authorization and used for validation
|
||||
|
||||
public ModuleControllerBase(ILogManager logger, IHttpContextAccessor accessor)
|
||||
{
|
||||
_logger = logger;
|
||||
if (accessor.HttpContext.Request.Query.ContainsKey("entityid"))
|
||||
{
|
||||
_entityId = int.Parse(accessor.HttpContext.Request.Query["entityid"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
@ -15,10 +15,11 @@ using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Xml.Linq;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class ModuleDefinitionController : Controller
|
||||
{
|
||||
private readonly IModuleDefinitionRepository _moduleDefinitions;
|
||||
@ -80,7 +81,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public void Put(int id, [FromBody] ModuleDefinition moduleDefinition)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -91,16 +92,16 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("install")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public void InstallModules()
|
||||
{
|
||||
_installationManager.InstallPackages("Modules", true);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Modules Installed");
|
||||
_installationManager.InstallPackages("Modules", true);
|
||||
}
|
||||
|
||||
// DELETE api/<controller>/5?siteid=x
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public void Delete(int id, int siteid)
|
||||
{
|
||||
ModuleDefinition moduledefinition = _moduleDefinitions.GetModuleDefinition(id, siteid);
|
||||
@ -110,6 +111,7 @@ namespace Oqtane.Controllers
|
||||
{
|
||||
Type moduletype = Type.GetType(moduledefinition.ServerManagerType);
|
||||
|
||||
// execute uninstall logic
|
||||
foreach (Tenant tenant in _tenants.GetTenants())
|
||||
{
|
||||
try
|
||||
@ -130,25 +132,28 @@ namespace Oqtane.Controllers
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Delete, "Error Uninstalling {ModuleDefinitionName} For Tenant {Tenant} {Error}", moduledefinition.ModuleDefinitionName, tenant.Name, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// use assets.json to clean up file resources
|
||||
string assetfilepath = Path.Combine(_environment.WebRootPath, "Modules", Utilities.GetTypeName(moduledefinition.ModuleDefinitionName), "assets.json");
|
||||
if (System.IO.File.Exists(assetfilepath))
|
||||
{
|
||||
List<string> assets = JsonSerializer.Deserialize<List<string>>(System.IO.File.ReadAllText(assetfilepath));
|
||||
foreach(string asset in assets)
|
||||
{
|
||||
if (System.IO.File.Exists(asset))
|
||||
{
|
||||
System.IO.File.Delete(asset);
|
||||
}
|
||||
}
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assets Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName);
|
||||
}
|
||||
|
||||
// clean up module static resource folder
|
||||
string folder = Path.Combine(_environment.WebRootPath, Path.Combine("Modules", Utilities.GetTypeName(moduledefinition.ModuleDefinitionName)));
|
||||
if (Directory.Exists(folder))
|
||||
{
|
||||
Directory.Delete(folder, true);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Static Resources Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName);
|
||||
}
|
||||
|
||||
// get root assembly name ( note that this only works if modules follow a specific naming convention for their assemblies )
|
||||
string assemblyname = Utilities.GetAssemblyName(moduledefinition.ModuleDefinitionName).ToLower();
|
||||
assemblyname = assemblyname.Replace(".client", "").Replace(".oqtane", "");
|
||||
|
||||
// remove module assemblies from /bin
|
||||
string binfolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
foreach (string file in Directory.EnumerateFiles(binfolder, assemblyname + "*.*"))
|
||||
{
|
||||
System.IO.File.Delete(file);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assembly {Filename} Removed For {ModuleDefinitionName}", file, moduledefinition.ModuleDefinitionName);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Resources Folder Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName);
|
||||
}
|
||||
|
||||
// remove module definition
|
||||
@ -163,26 +168,26 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>?moduleid=x
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public void Post([FromBody] ModuleDefinition moduleDefinition, string moduleid)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
string rootPath;
|
||||
DirectoryInfo rootFolder = Directory.GetParent(_environment.ContentRootPath);
|
||||
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", moduleDefinition.Template,"\\");
|
||||
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", moduleDefinition.Template,Path.DirectorySeparatorChar.ToString());
|
||||
|
||||
if (moduleDefinition.Template == "internal")
|
||||
{
|
||||
rootPath = Utilities.PathCombine(rootFolder.FullName,"\\");
|
||||
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + "s, Oqtane.Client";
|
||||
moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + "s.Manager." + moduleDefinition.Name + "Manager, Oqtane.Server";
|
||||
rootPath = Utilities.PathCombine(rootFolder.FullName,Path.DirectorySeparatorChar.ToString());
|
||||
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", Oqtane.Client";
|
||||
moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, Oqtane.Server";
|
||||
}
|
||||
else
|
||||
{
|
||||
rootPath = Utilities.PathCombine(rootFolder.Parent.FullName , moduleDefinition.Owner + "." + moduleDefinition.Name + "s","\\");
|
||||
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + "s, " + moduleDefinition.Owner + "." + moduleDefinition.Name + "s.Client.Oqtane";
|
||||
moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + "s.Manager." + moduleDefinition.Name + "Manager, " + moduleDefinition.Owner + "." + moduleDefinition.Name + "s.Server.Oqtane";
|
||||
rootPath = Utilities.PathCombine(rootFolder.Parent.FullName , moduleDefinition.Owner + "." + moduleDefinition.Name,Path.DirectorySeparatorChar.ToString());
|
||||
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Client.Oqtane";
|
||||
moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Server.Oqtane";
|
||||
}
|
||||
|
||||
ProcessTemplatesRecursively(new DirectoryInfo(templatePath), rootPath, rootFolder.Name, templatePath, moduleDefinition);
|
||||
@ -196,8 +201,8 @@ namespace Oqtane.Controllers
|
||||
{
|
||||
// add embedded resources to project
|
||||
List<string> resources = new List<string>();
|
||||
resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name + "s", "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + "s.1.0.0.sql"));
|
||||
resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name + "s", "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + "s.Uninstall.sql"));
|
||||
resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name, "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + ".1.0.0.sql"));
|
||||
resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name, "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + ".Uninstall.sql"));
|
||||
EmbedResourceFiles(Utilities.PathCombine(rootPath, "Oqtane.Server", "Oqtane.Server.csproj"), resources);
|
||||
}
|
||||
|
||||
@ -235,7 +240,20 @@ namespace Oqtane.Controllers
|
||||
text = text.Replace("[ServerManagerType]", moduleDefinition.ServerManagerType);
|
||||
text = text.Replace("[Folder]", folderPath);
|
||||
text = text.Replace("[File]", Path.GetFileName(filePath));
|
||||
text = text.Replace("[FrameworkVersion]", Constants.Version);
|
||||
if (moduleDefinition.Version == "local")
|
||||
{
|
||||
text = text.Replace("[FrameworkVersion]", Constants.Version);
|
||||
text = text.Replace("[ClientReference]", "<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Client.dll</HintPath></Reference>");
|
||||
text = text.Replace("[ServerReference]", "<Reference Include=\"Oqtane.Server\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Server.dll</HintPath></Reference>");
|
||||
text = text.Replace("[SharedReference]", "<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Shared.dll</HintPath></Reference>");
|
||||
}
|
||||
else
|
||||
{
|
||||
text = text.Replace("[FrameworkVersion]", moduleDefinition.Version);
|
||||
text = text.Replace("[ClientReference]", "<PackageReference Include=\"Oqtane.Client\" Version=\"" + moduleDefinition.Version + "\" />");
|
||||
text = text.Replace("[ServerReference]", "<PackageReference Include=\"Oqtane.Server\" Version=\"" + moduleDefinition.Version + "\" />");
|
||||
text = text.Replace("[SharedReference]", "<PackageReference Include=\"Oqtane.Shared\" Version=\"" + moduleDefinition.Version + "\" />");
|
||||
}
|
||||
System.IO.File.WriteAllText(filePath, text);
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ using Oqtane.Security;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class NotificationController : Controller
|
||||
{
|
||||
private readonly INotificationRepository _notifications;
|
||||
@ -26,7 +26,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>?siteid=x&type=y&userid=z
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public IEnumerable<Notification> Get(string siteid, string direction, string userid)
|
||||
{
|
||||
IEnumerable<Notification> notifications = null;
|
||||
@ -46,7 +46,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET api/<controller>/5
|
||||
[HttpGet("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Notification Get(int id)
|
||||
{
|
||||
Notification notification = _notifications.GetNotification(id);
|
||||
@ -59,7 +59,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Notification Post([FromBody] Notification notification)
|
||||
{
|
||||
if (IsAuthorized(notification.FromUserId))
|
||||
@ -72,7 +72,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Notification Put(int id, [FromBody] Notification notification)
|
||||
{
|
||||
if (IsAuthorized(notification.FromUserId))
|
||||
@ -85,7 +85,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
Notification notification = _notifications.GetNotification(id);
|
||||
|
@ -15,7 +15,7 @@ using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class PackageController : Controller
|
||||
{
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
@ -27,15 +27,14 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>?tag=x
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public async Task<IEnumerable<Package>> Get(string tag)
|
||||
{
|
||||
List<Package> packages = new List<Package>();
|
||||
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
CancellationToken token;
|
||||
var searchResult = await GetJson<SearchResult>(httpClient, "https://azuresearch-usnc.nuget.org/query?q=tags:oqtane", token);
|
||||
var searchResult = await GetJson<SearchResult>(httpClient, "https://azuresearch-usnc.nuget.org/query?q=tags:oqtane");
|
||||
foreach(Data data in searchResult.Data)
|
||||
{
|
||||
if (data.Tags.Contains(tag))
|
||||
@ -56,14 +55,13 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public async Task Post(string packageid, string version, string folder)
|
||||
{
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
CancellationToken token;
|
||||
folder = Path.Combine(_environment.WebRootPath, folder);
|
||||
var response = await httpClient.GetAsync("https://www.nuget.org/api/v2/package/" + packageid.ToLower() + "/" + version, token).ConfigureAwait(false);
|
||||
var response = await httpClient.GetAsync("https://www.nuget.org/api/v2/package/" + packageid.ToLower() + "/" + version).ConfigureAwait(false);
|
||||
response.EnsureSuccessStatusCode();
|
||||
string filename = packageid + "." + version + ".nupkg";
|
||||
using (var fileStream = new FileStream(Path.Combine(folder, filename), FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
@ -73,10 +71,10 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<T> GetJson<T>(HttpClient httpClient, string url, CancellationToken token)
|
||||
private async Task<T> GetJson<T>(HttpClient httpClient, string url)
|
||||
{
|
||||
Uri uri = new Uri(url);
|
||||
var response = await httpClient.GetAsync(uri, token).ConfigureAwait(false);
|
||||
var response = await httpClient.GetAsync(uri).ConfigureAwait(false);
|
||||
response.EnsureSuccessStatusCode();
|
||||
var stream = await response.Content.ReadAsStreamAsync();
|
||||
using (var streamReader = new StreamReader(stream))
|
||||
|
@ -13,7 +13,7 @@ using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class PageController : Controller
|
||||
{
|
||||
private readonly IPageRepository _pages;
|
||||
@ -102,7 +102,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Page Post([FromBody] Page page)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -115,7 +115,7 @@ namespace Oqtane.Controllers
|
||||
else
|
||||
{
|
||||
permissions = new List<Permission> {
|
||||
new Permission(PermissionNames.Edit, Constants.AdminRole, true)
|
||||
new Permission(PermissionNames.Edit, RoleNames.Admin, true)
|
||||
}.EncodePermissions();
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ namespace Oqtane.Controllers
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, page.SiteId);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Page Added {Page}", page);
|
||||
|
||||
if (!page.EditMode)
|
||||
if (!page.Path.StartsWith("admin/"))
|
||||
{
|
||||
var modules = _modules.GetModules(page.SiteId).Where(item => item.AllPages).ToList();
|
||||
foreach (Module module in modules)
|
||||
@ -147,7 +147,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>/5?userid=x
|
||||
[HttpPost("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Page Post(int id, string userid)
|
||||
{
|
||||
Page page = null;
|
||||
@ -163,7 +163,6 @@ namespace Oqtane.Controllers
|
||||
page.Order = 0;
|
||||
page.IsNavigation = false;
|
||||
page.Url = "";
|
||||
page.EditMode = false;
|
||||
page.ThemeType = parent.ThemeType;
|
||||
page.LayoutType = parent.LayoutType;
|
||||
page.DefaultContainerType = parent.DefaultContainerType;
|
||||
@ -214,7 +213,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Page Put(int id, [FromBody] Page page)
|
||||
{
|
||||
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Page, page.PageId, PermissionNames.Edit))
|
||||
@ -234,7 +233,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/?siteid=x&pageid=y&parentid=z
|
||||
[HttpPut]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public void Put(int siteid, int pageid, int? parentid)
|
||||
{
|
||||
if (_userPermissions.IsAuthorized(User, EntityNames.Page, pageid, PermissionNames.Edit))
|
||||
@ -262,7 +261,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
Page page = _pages.GetPage(id);
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Oqtane.Models;
|
||||
@ -11,7 +11,7 @@ using Oqtane.Security;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class PageModuleController : Controller
|
||||
{
|
||||
private readonly IPageModuleRepository _pageModules;
|
||||
@ -65,13 +65,13 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public PageModule Post([FromBody] PageModule pageModule)
|
||||
{
|
||||
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Page, pageModule.PageId, PermissionNames.Edit))
|
||||
{
|
||||
pageModule = _pageModules.AddPageModule(pageModule);
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Page, pageModule.PageId);
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, _tenants.GetAlias().SiteId);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Page Module Added {PageModule}", pageModule);
|
||||
}
|
||||
else
|
||||
@ -85,13 +85,13 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public PageModule Put(int id, [FromBody] PageModule pageModule)
|
||||
{
|
||||
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Module, pageModule.ModuleId, PermissionNames.Edit))
|
||||
{
|
||||
pageModule = _pageModules.UpdatePageModule(pageModule);
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Page, pageModule.PageId);
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, _tenants.GetAlias().SiteId);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Page Module Updated {PageModule}", pageModule);
|
||||
}
|
||||
else
|
||||
@ -105,7 +105,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/?pageid=x&pane=y
|
||||
[HttpPut]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public void Put(int pageid, string pane)
|
||||
{
|
||||
if (_userPermissions.IsAuthorized(User, EntityNames.Page, pageid, PermissionNames.Edit))
|
||||
@ -121,7 +121,7 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
order += 2;
|
||||
}
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Page, pageid);
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, _tenants.GetAlias().SiteId);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Page Module Order Updated {PageId} {Pane}", pageid, pane);
|
||||
}
|
||||
else
|
||||
@ -133,14 +133,14 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
PageModule pagemodule = _pageModules.GetPageModule(id);
|
||||
if (_userPermissions.IsAuthorized(User, EntityNames.Page, pagemodule.PageId, PermissionNames.Edit))
|
||||
{
|
||||
_pageModules.DeletePageModule(id);
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Page, pagemodule.PageId);
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, _tenants.GetAlias().SiteId);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Page Module Deleted {PageModuleId}", id);
|
||||
}
|
||||
else
|
||||
|
@ -9,7 +9,7 @@ using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class ProfileController : Controller
|
||||
{
|
||||
private readonly IProfileRepository _profiles;
|
||||
@ -37,7 +37,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public Profile Post([FromBody] Profile profile)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -50,7 +50,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public Profile Put(int id, [FromBody] Profile profile)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -63,7 +63,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
_profiles.DeleteProfile(id);
|
||||
|
@ -9,7 +9,7 @@ using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class RoleController : Controller
|
||||
{
|
||||
private readonly IRoleRepository _roles;
|
||||
@ -23,7 +23,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>?siteid=x
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public IEnumerable<Role> Get(string siteid)
|
||||
{
|
||||
return _roles.GetRoles(int.Parse(siteid));
|
||||
@ -31,7 +31,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET api/<controller>/5
|
||||
[HttpGet("{id}")]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Role Get(int id)
|
||||
{
|
||||
return _roles.GetRole(id);
|
||||
@ -39,7 +39,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public Role Post([FromBody] Role role)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -52,7 +52,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public Role Put(int id, [FromBody] Role role)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -65,7 +65,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
_roles.DeleteRole(id);
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
@ -10,19 +10,23 @@ using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class SettingController : Controller
|
||||
{
|
||||
private readonly ISettingRepository _settings;
|
||||
private readonly IPageModuleRepository _pageModules;
|
||||
private readonly IUserPermissions _userPermissions;
|
||||
private readonly ITenantResolver _tenants;
|
||||
private readonly ISyncManager _syncManager;
|
||||
private readonly ILogManager _logger;
|
||||
|
||||
public SettingController(ISettingRepository settings, IPageModuleRepository pageModules, IUserPermissions userPermissions, ILogManager logger)
|
||||
public SettingController(ISettingRepository settings, IPageModuleRepository pageModules, IUserPermissions userPermissions, ITenantResolver tenants, ISyncManager syncManager, ILogManager logger)
|
||||
{
|
||||
_settings = settings;
|
||||
_pageModules = pageModules;
|
||||
_userPermissions = userPermissions;
|
||||
_tenants = tenants;
|
||||
_syncManager = syncManager;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@ -67,6 +71,10 @@ namespace Oqtane.Controllers
|
||||
if (ModelState.IsValid && IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.Edit))
|
||||
{
|
||||
setting = _settings.AddSetting(setting);
|
||||
if (setting.EntityName == EntityNames.Module)
|
||||
{
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, _tenants.GetAlias().SiteId);
|
||||
}
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Setting Added {Setting}", setting);
|
||||
}
|
||||
else
|
||||
@ -85,6 +93,10 @@ namespace Oqtane.Controllers
|
||||
if (ModelState.IsValid && IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.Edit))
|
||||
{
|
||||
setting = _settings.UpdateSetting(setting);
|
||||
if (setting.EntityName == EntityNames.Module)
|
||||
{
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, _tenants.GetAlias().SiteId);
|
||||
}
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Setting Updated {Setting}", setting);
|
||||
}
|
||||
else
|
||||
@ -104,6 +116,10 @@ namespace Oqtane.Controllers
|
||||
if (IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.Edit))
|
||||
{
|
||||
_settings.DeleteSetting(id);
|
||||
if (setting.EntityName == EntityNames.Module)
|
||||
{
|
||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, _tenants.GetAlias().SiteId);
|
||||
}
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Setting Deleted {Setting}", setting);
|
||||
}
|
||||
else
|
||||
@ -124,10 +140,10 @@ namespace Oqtane.Controllers
|
||||
switch (entityName)
|
||||
{
|
||||
case EntityNames.Tenant:
|
||||
authorized = User.IsInRole(Constants.HostRole);
|
||||
authorized = User.IsInRole(RoleNames.Host);
|
||||
break;
|
||||
case EntityNames.Site:
|
||||
authorized = User.IsInRole(Constants.AdminRole);
|
||||
authorized = User.IsInRole(RoleNames.Admin);
|
||||
break;
|
||||
case EntityNames.Page:
|
||||
case EntityNames.Module:
|
||||
@ -138,7 +154,7 @@ namespace Oqtane.Controllers
|
||||
authorized = true;
|
||||
if (permissionName == PermissionNames.Edit)
|
||||
{
|
||||
authorized = User.IsInRole(Constants.AdminRole) || (_userPermissions.GetUser(User).UserId == entityId);
|
||||
authorized = User.IsInRole(RoleNames.Admin) || (_userPermissions.GetUser(User).UserId == entityId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class SiteController : Controller
|
||||
{
|
||||
private readonly ISiteRepository _sites;
|
||||
@ -28,7 +28,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public IEnumerable<Site> Get()
|
||||
{
|
||||
return _sites.GetSites();
|
||||
@ -57,7 +57,7 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
else
|
||||
{
|
||||
authorized = User.IsInRole(Constants.HostRole);
|
||||
authorized = User.IsInRole(RoleNames.Host);
|
||||
}
|
||||
if (authorized)
|
||||
{
|
||||
@ -70,7 +70,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public Site Put(int id, [FromBody] Site site)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -84,7 +84,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
_sites.DeleteSite(id);
|
||||
|
@ -7,7 +7,7 @@ using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class SiteTemplateController : Controller
|
||||
{
|
||||
private readonly ISiteTemplateRepository _siteTemplates;
|
||||
@ -19,7 +19,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public IEnumerable<SiteTemplate> Get()
|
||||
{
|
||||
return _siteTemplates.GetSiteTemplates();
|
||||
|
@ -14,7 +14,7 @@ using System;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class SqlController : Controller
|
||||
{
|
||||
private readonly ITenantRepository _tenants;
|
||||
@ -30,7 +30,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST: api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public SqlQuery Post([FromBody] SqlQuery sqlquery)
|
||||
{
|
||||
var results = new List<Dictionary<string, string>>();
|
||||
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class SystemController : Controller
|
||||
{
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
@ -19,7 +19,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public Dictionary<string, string> Get()
|
||||
{
|
||||
Dictionary<string, string> systeminfo = new Dictionary<string, string>();
|
||||
|
@ -9,7 +9,7 @@ using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class TenantController : Controller
|
||||
{
|
||||
private readonly ITenantRepository _tenants;
|
||||
@ -23,7 +23,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public IEnumerable<Tenant> Get()
|
||||
{
|
||||
return _tenants.GetTenants();
|
||||
@ -31,7 +31,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET api/<controller>/5
|
||||
[HttpGet("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public Tenant Get(int id)
|
||||
{
|
||||
return _tenants.GetTenant(id);
|
||||
@ -39,7 +39,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public Tenant Post([FromBody] Tenant tenant)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -52,7 +52,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public Tenant Put(int id, [FromBody] Tenant tenant)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
@ -65,7 +65,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public void Delete(int id)
|
||||
{
|
||||
_tenants.DeleteTenant(id);
|
||||
|
@ -10,12 +10,13 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Repository;
|
||||
using System.Text.Json;
|
||||
|
||||
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class ThemeController : Controller
|
||||
{
|
||||
private readonly IThemeRepository _themes;
|
||||
@ -33,63 +34,55 @@ namespace Oqtane.Controllers
|
||||
|
||||
// GET: api/<controller>
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.RegisteredRole)]
|
||||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public IEnumerable<Theme> Get()
|
||||
{
|
||||
return _themes.GetThemes();
|
||||
}
|
||||
|
||||
[HttpGet("install")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public void InstallThemes()
|
||||
{
|
||||
_installationManager.InstallPackages("Themes", true);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Themes Installed");
|
||||
_installationManager.InstallPackages("Themes", true);
|
||||
}
|
||||
|
||||
// DELETE api/<controller>/xxx
|
||||
[HttpDelete("{themename}")]
|
||||
[Authorize(Roles = Constants.HostRole)]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public void Delete(string themename)
|
||||
{
|
||||
List<Theme> themes = _themes.GetThemes().ToList();
|
||||
Theme theme = themes.Where(item => item.ThemeName == themename).FirstOrDefault();
|
||||
if (theme != null && Utilities.GetAssemblyName(theme.ThemeName) != "Oqtane.Client")
|
||||
{
|
||||
// use assets.json to clean up file resources
|
||||
string assetfilepath = Path.Combine(_environment.WebRootPath, "Themes", Utilities.GetTypeName(theme.ThemeName), "assets.json");
|
||||
if (System.IO.File.Exists(assetfilepath))
|
||||
{
|
||||
List<string> assets = JsonSerializer.Deserialize<List<string>>(System.IO.File.ReadAllText(assetfilepath));
|
||||
foreach (string asset in assets)
|
||||
{
|
||||
if (System.IO.File.Exists(asset))
|
||||
{
|
||||
System.IO.File.Delete(asset);
|
||||
}
|
||||
}
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Assets Removed For {ThemeName}", theme.ThemeName);
|
||||
}
|
||||
|
||||
// clean up theme static resource folder
|
||||
string folder = Path.Combine(_environment.WebRootPath, "Themes" , Utilities.GetTypeName(theme.ThemeName));
|
||||
if (Directory.Exists(folder))
|
||||
{
|
||||
Directory.Delete(folder, true);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Static Resources Removed For {ThemeName}", theme.ThemeName);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Resource Folder Removed For {ThemeName}", theme.ThemeName);
|
||||
}
|
||||
|
||||
// remove theme assembly from /bin
|
||||
string binfolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
System.IO.File.Delete(Path.Combine(binfolder, Utilities.GetAssemblyName(theme.ThemeName) + ".dll"));
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Assembly {Filename} Removed For {ThemeName}", Utilities.GetAssemblyName(theme.ThemeName) + ".dll", themename);
|
||||
|
||||
_installationManager.RestartApplication();
|
||||
}
|
||||
}
|
||||
|
||||
// GET api/<controller>/load/assembyname
|
||||
[HttpGet("load/{assemblyname}")]
|
||||
public IActionResult Load(string assemblyname)
|
||||
{
|
||||
if (Path.GetExtension(assemblyname).ToLower() == ".dll")
|
||||
{
|
||||
string binfolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
byte[] file = System.IO.File.ReadAllBytes(Path.Combine(binfolder, assemblyname));
|
||||
return File(file, "application/octet-stream", assemblyname);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Download Assembly {Assembly}", assemblyname);
|
||||
HttpContext.Response.StatusCode = 401;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -9,14 +9,16 @@ using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Oqtane.Shared;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Repository;
|
||||
using Oqtane.Extensions;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route("{alias}/api/[controller]")]
|
||||
[Route(ControllerRoutes.Default)]
|
||||
public class UserController : Controller
|
||||
{
|
||||
private readonly IUserRepository _users;
|
||||
@ -75,7 +77,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
private User Filter(User user)
|
||||
{
|
||||
if (user != null && !User.IsInRole(Constants.AdminRole) && User.Identity.Name?.ToLower() != user.Username.ToLower())
|
||||
if (user != null && !User.IsInRole(RoleNames.Admin) && User.Identity.Name?.ToLower() != user.Username.ToLower())
|
||||
{
|
||||
user.DisplayName = "";
|
||||
user.Email = "";
|
||||
@ -116,7 +118,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
bool verified;
|
||||
bool allowregistration;
|
||||
if (user.Username == Constants.HostUser || User.IsInRole(Constants.AdminRole))
|
||||
if (user.Username == UserNames.Host || User.IsInRole(RoleNames.Admin))
|
||||
{
|
||||
verified = true;
|
||||
allowregistration = true;
|
||||
@ -162,9 +164,9 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
|
||||
// assign to host role if this is the host user ( initial installation )
|
||||
if (user.Username == Constants.HostUser)
|
||||
if (user.Username == UserNames.Host)
|
||||
{
|
||||
int hostroleid = _roles.GetRoles(user.SiteId, true).Where(item => item.Name == Constants.HostRole).FirstOrDefault().RoleId;
|
||||
int hostroleid = _roles.GetRoles(user.SiteId, true).Where(item => item.Name == RoleNames.Host).FirstOrDefault().RoleId;
|
||||
UserRole userrole = new UserRole();
|
||||
userrole.UserId = newUser.UserId;
|
||||
userrole.RoleId = hostroleid;
|
||||
@ -174,7 +176,7 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
|
||||
// add folder for user
|
||||
Folder folder = _folders.GetFolder(user.SiteId, Utilities.PathCombine("Users","\\"));
|
||||
Folder folder = _folders.GetFolder(user.SiteId, Utilities.PathCombine("Users",Path.DirectorySeparatorChar.ToString()));
|
||||
if (folder != null)
|
||||
{
|
||||
_folders.AddFolder(new Folder
|
||||
@ -182,11 +184,15 @@ namespace Oqtane.Controllers
|
||||
SiteId = folder.SiteId,
|
||||
ParentId = folder.FolderId,
|
||||
Name = "My Folder",
|
||||
Path = Utilities.PathCombine(folder.Path, newUser.UserId.ToString(),"\\"),
|
||||
Path = Utilities.PathCombine(folder.Path, newUser.UserId.ToString(),Path.DirectorySeparatorChar.ToString()),
|
||||
Order = 1,
|
||||
IsSystem = true,
|
||||
Permissions = "[{\"PermissionName\":\"Browse\",\"Permissions\":\"[" + newUser.UserId.ToString() + "]\"},{\"PermissionName\":\"View\",\"Permissions\":\"All Users\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"[" +
|
||||
newUser.UserId.ToString() + "]\"}]"
|
||||
Permissions = new List<Permission>
|
||||
{
|
||||
new Permission(PermissionNames.Browse, newUser.UserId, true),
|
||||
new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||
new Permission(PermissionNames.Edit, newUser.UserId, true)
|
||||
}.EncodePermissions()
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -200,7 +206,7 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
if (newUser != null && user.Username != Constants.HostUser)
|
||||
if (newUser != null && user.Username != UserNames.Host)
|
||||
{
|
||||
// add auto assigned roles to user for site
|
||||
List<Role> roles = _roles.GetRoles(user.SiteId).Where(item => item.IsAutoAssigned).ToList();
|
||||
@ -236,7 +242,7 @@ namespace Oqtane.Controllers
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
if (User.IsInRole(Constants.AdminRole) || User.Identity.Name == user.Username)
|
||||
if (User.IsInRole(RoleNames.Admin) || User.Identity.Name == user.Username)
|
||||
{
|
||||
if (user.Password != "")
|
||||
{
|
||||
@ -264,7 +270,7 @@ namespace Oqtane.Controllers
|
||||
|
||||
// DELETE api/<controller>/5?siteid=x
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public async Task Delete(int id)
|
||||
{
|
||||
IdentityUser identityuser = await _identityUserManager.FindByNameAsync(_users.GetUser(id).Username);
|
||||
@ -454,9 +460,9 @@ namespace Oqtane.Controllers
|
||||
foreach (UserRole userrole in userroles)
|
||||
{
|
||||
roles += userrole.Role.Name + ";";
|
||||
if (userrole.Role.Name == Constants.HostRole && userroles.Where(item => item.Role.Name == Constants.AdminRole).FirstOrDefault() == null)
|
||||
if (userrole.Role.Name == RoleNames.Host && userroles.Where(item => item.Role.Name == RoleNames.Admin).FirstOrDefault() == null)
|
||||
{
|
||||
roles += Constants.AdminRole + ";";
|
||||
roles += RoleNames.Admin + ";";
|
||||
}
|
||||
}
|
||||
if (roles != "") roles = ";" + roles;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user