Folder and file management service

This commit is contained in:
Shaun Walker 2020-02-11 14:25:38 -05:00
parent ee682516c3
commit 6a92c9f764
45 changed files with 1075 additions and 421 deletions

View File

@ -2,55 +2,109 @@
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IFileService FileService
@inject IFolderService FolderService
<table class="table table-borderless">
<tr>
<td>
<label for="Name" class="control-label">Files: </label>
</td>
<td>
<FileUpload Multiple="true" @ref="fileupload"></FileUpload>
</td>
</tr>
</table>
<button type="button" class="btn btn-primary" @onclick="UploadFile">Upload</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
@if (folders != null)
{
<div class="container-fluid">
<div class="form-group">
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#Upload" role="tab">
Upload Files
</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#Download" role="tab">
Download Files
</a>
</li>
</ul>
<div class="tab-content">
<div id="Upload" class="tab-pane fade show active" role="tabpanel">
<table class="table table-borderless">
<tr>
<td>
<label for="Name" class="control-label">Upload: </label>
</td>
<td>
<FileManager UploadMultiple="true" ShowFiles="false" FolderId="@folderid.ToString()" />
</td>
</tr>
</table>
</div>
<div id="Download" class="tab-pane fade" role="tabpanel">
<table class="table table-borderless">
<tr>
<td>
<label for="Name" class="control-label">Url: </label>
</td>
<td>
<input class="form-control" @bind="@url" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Folder: </label>
</td>
<td>
<select class="form-control" @bind="@folderid">
<option value="-1">&lt;Select Folder&gt;</option>
@foreach (Folder folder in folders)
{
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
}
</select>
</td>
</tr>
</table>
<button type="button" class="btn btn-primary" @onclick="Download">Download</button>
</div>
</div>
</div>
</div>
<br />
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
}
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
FileUpload fileupload;
string url = "";
List<Folder> folders;
int folderid = -1;
private async Task UploadFile()
protected override async Task OnInitializedAsync()
{
string[] files = await fileupload.GetFiles();
if (files.Length > 0)
{
try
{
ShowProgressIndicator();
folders = await FolderService.GetFoldersAsync(ModuleState.SiteId);
string result = await FileService.UploadFilesAsync(PageState.Site.SiteRootPath, files, "");
if (result == "")
{
await logger.LogInformation("Files Uploaded Successfully");
AddModuleMessage("Files Uploaded Successfully", MessageType.Success);
}
else
{
await logger.LogError("Upload Failed For {Files}", result.Replace(",",", "));
AddModuleMessage("Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
}
}
catch (Exception ex)
if (PageState.QueryString.ContainsKey("id"))
{
folderid = int.Parse(PageState.QueryString["id"]);
}
}
private async Task Download()
{
try
{
if (url != "" && folderid != -1)
{
await logger.LogError(ex, "Upload Failed {Error}", ex.Message);
AddModuleMessage("Upload Failed. " + ex.Message, MessageType.Error);
await FileService.UploadFileAsync(url, folderid);
await logger.LogInformation("File Downloaded Successfully From Url {Url}", url);
AddModuleMessage("File Downloaded Successfully From Url", MessageType.Success);
}
else
{
AddModuleMessage("You Must Enter A Url And Select A Folder", MessageType.Warning);
}
}
else
catch (Exception ex)
{
AddModuleMessage("You Must Select Some Files To Upload", MessageType.Warning);
await logger.LogError(ex, "Error Downloading File From Url {Url} {Error}", url, ex.Message);
AddModuleMessage("Error Downloading File From Url. Please Verify That The Url Is Valid.", MessageType.Error);
}
}
}

View File

@ -3,36 +3,70 @@
@inject IFolderService FolderService
@inject NavigationManager NavigationManager
<table class="table table-borderless">
<tr>
<td>
<label for="Name" class="control-label">Name: </label>
</td>
<td>
<input class="form-control" @bind="@name" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Permissions: </label>
</td>
<td>
<PermissionGrid EntityName="Folder" PermissionNames="View,Edit" Permissions="@permissions" @ref="permissiongrid" />
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveFolder">Save</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
<br />
<br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
@if (folders != null)
{
<table class="table table-borderless">
<tr>
<td>
<label for="Name" class="control-label">Parent: </label>
</td>
<td>
<select class="form-control" @bind="@parentid">
@if (PageState.QueryString.ContainsKey("id"))
{
<option value="-1">&lt;No Parent&gt;</option>
}
@foreach (Folder folder in folders)
{
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
}
</select>
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Name: </label>
</td>
<td>
<input class="form-control" @bind="@name" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Permissions: </label>
</td>
<td>
<PermissionGrid EntityName="Folder" PermissionNames="Browse,View,Edit" Permissions="@permissions" @ref="permissiongrid" />
</td>
</tr>
</table>
@if (!issystem)
{
<button type="button" class="btn btn-success" @onclick="SaveFolder">Save</button>
}
<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>
}
<br />
<br />
@if (PageState.QueryString.ContainsKey("id"))
{
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
}
}
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
public override string Title { get { return "Folder Management"; } }
int FolderId;
List<Folder> folders;
int folderid;
string name;
string permissions;
int parentid = -1;
bool issystem = false;
string permissions = "";
string createdby;
DateTime createdon;
string modifiedby;
@ -44,22 +78,38 @@
{
try
{
FolderId = Int32.Parse(PageState.QueryString["id"]);
Folder folder = await FolderService.GetFolderAsync(FolderId);
if (folder != null)
folders = await FolderService.GetFoldersAsync(PageState.Site.SiteId);
if (PageState.QueryString.ContainsKey("id"))
{
name = folder.Name;
permissions = folder.Permissions;
createdby = folder.CreatedBy;
createdon = folder.CreatedOn;
modifiedby = folder.ModifiedBy;
modifiedon = folder.ModifiedOn;
folderid = Int32.Parse(PageState.QueryString["id"]);
Folder folder = await FolderService.GetFolderAsync(folderid);
if (folder != null)
{
parentid = (folder.ParentId == null) ? -1 : folder.ParentId.Value;
name = folder.Name;
issystem = folder.IsSystem;
permissions = folder.Permissions;
createdby = folder.CreatedBy;
createdon = folder.CreatedOn;
modifiedby = folder.ModifiedBy;
modifiedon = folder.ModifiedOn;
}
}
else
{
parentid = folders[0].FolderId;
List<PermissionString> permissionstrings = new List<PermissionString>();
permissionstrings.Add(new PermissionString { PermissionName = "Browse", Permissions = Constants.AdminRole });
permissionstrings.Add(new PermissionString { PermissionName = "View", Permissions = Constants.AdminRole });
permissionstrings.Add(new PermissionString { PermissionName = "Edit", Permissions = Constants.AdminRole });
permissions = UserSecurity.SetPermissionStrings(permissionstrings);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Folder {FolderId} {Error}", FolderId, ex.Message);
AddModuleMessage("Error Loading Module", MessageType.Error);
await logger.LogError(ex, "Error Loading Folder {FolderId} {Error}", folderid, ex.Message);
AddModuleMessage("Error Loading Folder", MessageType.Error);
}
}
@ -67,19 +117,67 @@
{
try
{
Folder folder = await FolderService.GetFolderAsync(FolderId);
if (folder != null)
if (name != "" && parentid != -1)
{
Folder folder;
if (folderid != -1)
{
folder = await FolderService.GetFolderAsync(folderid);
}
else
{
folder = new Folder();
}
folder.SiteId = PageState.Site.SiteId;
if (parentid == -1)
{
folder.ParentId = null;
}
else
{
folder.ParentId = parentid;
}
folder.Name = name;
folder.IsSystem = issystem;
folder.Permissions = permissiongrid.GetPermissions();
await FolderService.UpdateFolderAsync(folder);
if (folderid != -1)
{
folder = await FolderService.UpdateFolderAsync(folder);
}
else
{
folder = await FolderService.AddFolderAsync(folder);
}
await FolderService.UpdateFolderOrderAsync(folder.SiteId, folder.FolderId, folder.ParentId);
await logger.LogInformation("Folder Saved {Folder}", folder);
NavigationManager.NavigateTo(NavigateUrl(Reload.Site));
}
else
{
AddModuleMessage("Folders Must Have A Parent And A Name", MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving Folder {FolderId} {Error}", FolderId, ex.Message);
await logger.LogError(ex, "Error Saving Folder {FolderId} {Error}", folderid, ex.Message);
AddModuleMessage("Error Saving Module", MessageType.Error);
}
}
private async Task DeleteFolder()
{
try
{
await FolderService.DeleteFolderAsync(folderid);
await logger.LogInformation("Folder Deleted {Folder}", folderid);
AddModuleMessage("Folder Deleted", MessageType.Success);
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting Folder {Folder} {Error}", folderid, ex.Message);
AddModuleMessage("Error Deleting Folder", MessageType.Error);
}
}
}

View File

@ -1,39 +1,71 @@
@namespace Oqtane.Modules.Admin.Files
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IFolderService FolderService
@inject IFileService FileService
@if (Files == null)
@if (Files != null)
{
<p><em>Loading...</em></p>
}
else
{
<ActionLink Action="Add" Text="Add Files" />
<table class="table table-borderless">
<tr>
<td>
<label for="Name" class="control-label">Folder: </label>
</td>
<td>
<select class="form-control" @onchange="(e => FolderChanged(e))">
@foreach (Folder folder in Folders)
{
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
}
</select>
</td>
<td>
<ActionLink Action="Edit" Text="Edit Folder" Class="btn btn-secondary" Parameters="@($"id=" + folderid.ToString())" />&nbsp;
<ActionLink Action="Edit" Text="Add Folder" Class="btn btn-secondary" />&nbsp;
<ActionLink Action="Add" Text="Upload Files" Parameters="@($"id=" + folderid.ToString())" />
</td>
</tr>
</table>
<Pager Items="@Files">
<Header>
<th>&nbsp;</th>
<th>Name</th>
<th>Modified</th>
<th>Type</th>
<th>Size</th>
</Header>
<Row>
<td><ActionDialog Header="Delete File" Message="@("Are You Sure You Wish To Delete " + context + "?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFile(context))" /></td>
<td><a href="@(uri.Scheme + "://" + uri.Authority + "/" + PageState.Site.SiteRootPath + context)" target="_new">@context</a></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>
<td>@context.Extension.ToUpper() File</td>
<td>@(context.Size / 1000) KB</td>
</Row>
</Pager>
@if (Files.Count == 0)
{
<div class="text-center">No Files Exist In Selected Folder</div>
}
}
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
List<string> Files;
List<Folder> Folders;
int folderid;
List<File> Files;
Uri uri;
protected override async Task OnParametersSetAsync()
{
try
{
Files = await FileService.GetFilesAsync(PageState.Site.SiteRootPath);
Folders = await FolderService.GetFoldersAsync(PageState.Site.SiteId);
if (Folders.Count > 0)
{
folderid = Folders[0].FolderId;
await GetFiles();
}
uri = new Uri(NavigationManager.Uri);
}
catch (Exception ex)
@ -43,19 +75,40 @@ else
}
}
private async Task DeleteFile(string filename)
private async Task GetFiles()
{
Files = await FileService.GetFilesAsync(folderid);
}
private async void FolderChanged(ChangeEventArgs e)
{
try
{
await FileService.DeleteFileAsync(PageState.Site.SiteRootPath, filename);
Files = await FileService.GetFilesAsync(PageState.Site.SiteRootPath);
await logger.LogInformation("File Deleted {File}", filename);
AddModuleMessage("File " + filename + " Deleted", MessageType.Success);
folderid = int.Parse((string)e.Value);
await GetFiles();
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting File {File} {Error}", filename, ex.Message);
AddModuleMessage("Error Deleting File " + filename, MessageType.Error);
await logger.LogError(ex, "Error Loading Files {Error}", ex.Message);
AddModuleMessage("Error Loading Files", MessageType.Error);
}
}
}
private async Task DeleteFile(File file)
{
try
{
await FileService.DeleteFileAsync(file.FileId);
await logger.LogInformation("File Deleted {File}", file.Name);
AddModuleMessage("File " + file.Name + " Deleted", MessageType.Success);
await GetFiles();
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting File {File} {Error}", file.Name, ex.Message);
AddModuleMessage("Error Deleting File " + file.Name, MessageType.Error);
}
}
}

View File

@ -11,11 +11,10 @@
<label for="Name" class="control-label">Module: </label>
</td>
<td>
<FileUpload Filter=".nupkg" @ref="fileupload"></FileUpload>
<FileManager Filter=".nupkg" ShowFiles="false" Folder="Modules" />
</td>
</tr>
</table>
<button type="button" class="btn btn-primary" @onclick="UploadFile">Upload Module</button>
@if (packages != null)
{
@ -38,19 +37,14 @@
</Pager>
}
@if (uploaded)
{
<button type="button" class="btn btn-success" @onclick="InstallModules">Install</button>
}
<button type="button" class="btn btn-success" @onclick="InstallModules">Install</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
bool uploaded = false;
List<Package> packages;
FileUpload fileupload;
protected override async Task OnInitializedAsync()
{
@ -73,47 +67,6 @@
}
}
private async Task UploadFile()
{
string[] files = await fileupload.GetFiles();
if (files.Length > 0)
{
if (files[0].Contains(".Module."))
{
try
{
string result = await FileService.UploadFilesAsync("Modules", files, "");
if (result == "")
{
await logger.LogInformation("Module Uploaded Successfully {Package}", files[0]);
AddModuleMessage("Module Uploaded Successfully. Click Install To Complete Installation.", MessageType.Success);
uploaded = true;
StateHasChanged();
}
else
{
await logger.LogError("Module Upload Failed For {Package}", files[0]);
AddModuleMessage("Module Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Module Upload Failed For {Package} {Error}", files[0], ex.Message);
AddModuleMessage("Module Upload Failed.", MessageType.Error);
}
}
else
{
await logger.LogError("Invalid Module Package {Package}", files[0]);
AddModuleMessage("Invalid Module Package", MessageType.Error);
}
}
else
{
AddModuleMessage("You Must Select A Module To Upload", MessageType.Warning);
}
}
private async Task InstallModules()
{
try
@ -134,7 +87,6 @@
await PackageService.DownloadPackageAsync(moduledefinitionname, version, "Modules");
await logger.LogInformation("Module {ModuleDefinitionName} {Version} Downloaded Successfully", moduledefinitionname, version);
AddModuleMessage("Module Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success);
uploaded = true;
StateHasChanged();
}
catch (Exception ex)

View File

@ -161,7 +161,7 @@
string themetype = "";
string layouttype = "";
string icon = "";
string permissions = ""; // need to set default permissions
string permissions = "";
PermissionGrid permissiongrid;

View File

@ -49,7 +49,7 @@ else
<label for="Name" class="control-label">Logo: </label>
</td>
<td>
<input class="form-control" @bind="@logo" />
<FileManager @ref="filemanager" />
</td>
</tr>
<tr>
@ -129,7 +129,7 @@ else
string tenantid = "-1";
string name = "";
string urls = "";
string logo = "";
FileManager filemanager;
string themetype = "";
string layouttype = "";
string containertype = "";
@ -223,7 +223,12 @@ else
Site site = new Site();
site.TenantId = int.Parse(tenantid);
site.Name = name;
site.Logo = (logo == null ? "" : logo);
site.LogoFileId = null;
int logofileid = filemanager.GetFileId();
if (logofileid != -1)
{
site.LogoFileId = logofileid;
}
site.DefaultThemeType = themetype;
site.DefaultLayoutType = (layouttype == null ? "" : layouttype);
site.DefaultContainerType = containertype;

View File

@ -6,12 +6,8 @@
@inject IThemeService ThemeService
@inject ISettingService SettingService
@if (themes == null)
{
<p><em>Loading...</em></p>
}
else
{
@if (themes != null)
{
<table class="table table-borderless">
<tr>
<td>
@ -34,7 +30,7 @@ else
<label for="Name" class="control-label">Logo: </label>
</td>
<td>
<input class="form-control" @bind="@logo" />
<FileManager FileId="@logofileid.ToString()" @ref="filemanager" />
</td>
</tr>
<tr>
@ -157,16 +153,17 @@ else
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
Dictionary<string, string> themes = new Dictionary<string, string>();
Dictionary<string, string> panelayouts = new Dictionary<string, string>();
Dictionary<string, string> containers = new Dictionary<string, string>();
Dictionary<string, string> themes;
Dictionary<string, string> panelayouts;
Dictionary<string, string> containers;
Alias Alias;
int siteid;
string name = "";
List<Alias> aliases;
string urls = "";
string logo = "";
int logofileid = -1;
FileManager filemanager;
string themetype;
string layouttype;
string containertype;
@ -189,9 +186,6 @@ else
{
try
{
themes = ThemeService.GetThemeTypes(PageState.Themes);
containers = ThemeService.GetContainerTypes(PageState.Themes);
Alias = PageState.Aliases.Where(item => item.AliasId == Int32.Parse(PageState.QueryString["id"])).FirstOrDefault();
siteid = Alias.SiteId;
Site site = await SiteService.GetSiteAsync(siteid, Alias);
@ -203,7 +197,10 @@ else
{
urls += alias.Name + "\n";
}
logo = site.Logo;
if (site.LogoFileId != null)
{
logofileid = site.LogoFileId.Value;
}
themetype = site.DefaultThemeType;
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype);
layouttype = site.DefaultLayoutType;
@ -224,6 +221,9 @@ else
deletedon = site.DeletedOn;
isdeleted = site.IsDeleted.ToString();
}
themes = ThemeService.GetThemeTypes(PageState.Themes);
containers = ThemeService.GetContainerTypes(PageState.Themes);
}
catch (Exception ex)
{
@ -264,7 +264,12 @@ else
if (site != null)
{
site.Name = name;
site.Logo = (logo == null ? "" : logo);
site.LogoFileId = null;
int logofileid = filemanager.GetFileId();
if (logofileid != -1)
{
site.LogoFileId = logofileid;
}
site.DefaultThemeType = themetype;
site.DefaultLayoutType = (layouttype == null ? "" : layouttype);
site.DefaultContainerType = containertype;

View File

@ -11,11 +11,10 @@
<label for="Name" class="control-label">Theme: </label>
</td>
<td>
<FileUpload Filter=".nupkg" @ref="fileupload"></FileUpload>
<FileManager Filter=".nupkg" ShowFiles="false" Folder="Themes" />
</td>
</tr>
</table>
<button type="button" class="btn btn-primary" @onclick="UploadTheme">Upload Theme</button>
@if (packages != null)
{
@ -38,18 +37,13 @@
</Pager>
}
@if (uploaded)
{
<button type="button" class="btn btn-success" @onclick="InstallThemes">Install</button>
}
<button type="button" class="btn btn-success" @onclick="InstallThemes">Install</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
bool uploaded = false;
List<Package> packages;
FileUpload fileupload;
protected override async Task OnInitializedAsync()
{
@ -64,47 +58,6 @@
}
}
private async Task UploadTheme()
{
string[] files = await fileupload.GetFiles();
if (files.Length > 0)
{
if (files[0].Contains(".Theme."))
{
try
{
string result = await FileService.UploadFilesAsync("Themes", files, "");
if (result == "")
{
await logger.LogInformation("Theme Uploaded {Package}", files[0]);
AddModuleMessage("Theme Uploaded Successfully. Click Install To Complete Installation.", MessageType.Success);
uploaded = true;
StateHasChanged();
}
else
{
await logger.LogInformation("Theme Upload Failed For {Package}", result.Replace(",",", "));
AddModuleMessage("Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Theme Upload Failed {Package} {Error}", files[0], ex.Message);
AddModuleMessage("Theme Upload Failed", MessageType.Error);
}
}
else
{
await logger.LogError("Invalid Theme Package {Package}", files[0]);
AddModuleMessage("Invalid Theme Package", MessageType.Error);
}
}
else
{
AddModuleMessage("You Must Select A Theme To Upload", MessageType.Warning);
}
}
private async Task InstallThemes()
{
await ThemeService.InstallThemesAsync();
@ -115,7 +68,6 @@
{
await PackageService.DownloadPackageAsync(packageid, version, "Themes");
AddModuleMessage("Theme Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success);
uploaded = true;
StateHasChanged();
}
}

View File

@ -11,18 +11,11 @@
<label for="Name" class="control-label">Framework: </label>
</td>
<td>
<FileUpload Filter=".nupkg" @ref="fileupload"></FileUpload>
<FileManager Filter=".nupkg" ShowFiles="false" Folder="Framework" />
</td>
</tr>
</table>
@if (uploaded)
{
<button type="button" class="btn btn-success" @onclick="Upgrade">Upgrade</button>
}
else
{
<button type="button" class="btn btn-primary" @onclick="UploadFile">Upload</button>
}
<button type="button" class="btn btn-success" @onclick="Upgrade">Upgrade</button>
@if (upgradeavailable)
{
@ -35,9 +28,7 @@ else
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
bool uploaded = false;
bool upgradeavailable = false;
FileUpload fileupload;
protected override async Task OnInitializedAsync()
{
@ -53,47 +44,6 @@ else
}
}
private async Task UploadFile()
{
string[] files = await fileupload.GetFiles();
if (files.Length > 0)
{
if (files[0].Contains(".Framework."))
{
try
{
string result = await FileService.UploadFilesAsync("Framework", files, "");
if (result == "")
{
await logger.LogInformation("Framework Uploaded {Package}", files[0]);
AddModuleMessage("Framework Uploaded Successfully. Click Upgrade To Complete Installation.", MessageType.Success);
uploaded = true;
StateHasChanged();
}
else
{
await logger.LogInformation("Framework Upload Failed For {Package}", result.Replace(",",", "));
AddModuleMessage("Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Framework Upload Failed {Package} {Error}", files[0], ex.Message);
AddModuleMessage("Framework Upload Failed. " + ex.Message, MessageType.Error);
}
}
else
{
await logger.LogError("Invalid Framework Package {Package}", files[0]);
AddModuleMessage("Invalid Framework Package", MessageType.Error);
}
}
else
{
AddModuleMessage("You Must Select A Framework Package To Upload", MessageType.Warning);
}
}
private async Task Upgrade()
{
await InstallationService.Upgrade();

View File

@ -26,7 +26,14 @@
<div class="tab-content">
<div id="Profile" class="tab-pane fade show active" role="tabpanel">
<br />
@if (photofileid != -1)
{
<img src="@(ContentUrl(photofileid))" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
}
else
{
<br />
}
<table class="table table-borderless">
<tr>
<td>
@ -68,6 +75,14 @@
<input class="form-control" @bind="@displayname" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Photo: </label>
</td>
<td>
<FileManager FileId="@photofileid.ToString()" @ref="filemanager" />
</td>
</tr>
@foreach (Profile profile in profiles)
{
@ -164,6 +179,8 @@
string confirm = "";
string email = "";
string displayname = "";
FileManager filemanager;
int photofileid = -1;
List<Profile> profiles;
Dictionary<string, string> settings;
string category = "";
@ -179,6 +196,10 @@
username = PageState.User.Username;
email = PageState.User.Email;
displayname = PageState.User.DisplayName;
if (PageState.User.PhotoFileId != null)
{
photofileid = PageState.User.PhotoFileId.Value;
}
profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
await LoadNotificationsAsync();
@ -210,7 +231,7 @@
{
try
{
if (password != "" && confirm != "" && email != "")
if (username != "" && email != "")
{
if (password == confirm)
{
@ -219,11 +240,15 @@
user.Password = password;
user.Email = email;
user.DisplayName = (displayname == "" ? username : displayname);
user.PhotoFileId = null;
photofileid = filemanager.GetFileId();
if (photofileid != -1)
{
user.PhotoFileId = photofileid;
}
await UserService.UpdateUserAsync(user);
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
await logger.LogInformation("User Profile Saved");
NavigationManager.NavigateTo(NavigateUrl(""));
}
else
{
@ -232,7 +257,7 @@
}
else
{
AddModuleMessage("You Must Provide A Username, Password, and Email Address", MessageType.Warning);
AddModuleMessage("You Must Provide A Username and Email Address", MessageType.Warning);
}
}
catch (Exception ex)

View File

@ -48,6 +48,14 @@
<input class="form-control" @bind="@displayname" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Photo: </label>
</td>
<td>
<FileManager @ref="filemanager" />
</td>
</tr>
@foreach (Profile profile in profiles)
{
@ -83,6 +91,7 @@
string confirm = "";
string email = "";
string displayname = "";
FileManager filemanager;
List<Profile> profiles;
Dictionary<string, string> settings;
string category = "";
@ -115,6 +124,12 @@
user.Password = password;
user.Email = email;
user.DisplayName = string.IsNullOrWhiteSpace(displayname) ? username : displayname;
user.PhotoFileId = null;
int photofileid = filemanager.GetFileId();
if (photofileid != -1)
{
user.PhotoFileId = photofileid;
}
user = await UserService.AddUserAsync(user);

View File

@ -7,6 +7,14 @@
@if (profiles != null)
{
@if (photofileid != -1)
{
<img src="@(ContentUrl(photofileid))" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
}
else
{
<br />
}
<table class="table table-borderless">
<tr>
<td>
@ -48,6 +56,14 @@
<input class="form-control" @bind="@displayname" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Photo: </label>
</td>
<td>
<FileManager FileId="@photofileid.ToString()" @ref="filemanager" />
</td>
</tr>
@foreach (Profile profile in profiles)
{
@ -98,6 +114,8 @@
string confirm = "";
string email = "";
string displayname = "";
FileManager filemanager;
int photofileid = -1;
List<Profile> profiles;
Dictionary<string, string> settings;
string category = "";
@ -122,6 +140,10 @@
username = user.Username;
email = user.Email;
displayname = user.DisplayName;
if (user.PhotoFileId != null)
{
photofileid = user.PhotoFileId.Value;
}
settings = await SettingService.GetUserSettingsAsync(user.UserId);
createdby = user.CreatedBy;
createdon = user.CreatedOn;
@ -158,6 +180,12 @@
user.Password = password;
user.Email = email;
user.DisplayName = string.IsNullOrWhiteSpace(displayname) ? username : displayname;
user.PhotoFileId = null;
photofileid = filemanager.GetFileId();
if (photofileid != -1)
{
user.PhotoFileId = photofileid;
}
user.IsDeleted = (isdeleted == null ? true : Boolean.Parse(isdeleted));
user = await UserService.UpdateUserAsync(user);

View File

@ -0,0 +1,285 @@
@namespace Oqtane.Modules.Controls
@inherits ModuleBase
@inject IFolderService FolderService
@inject IFileService FileService
@inject IJSRuntime jsRuntime
@if (folders != null)
{
<select class="form-control" @onchange="(e => FolderChanged(e))">
@if (string.IsNullOrEmpty(Folder))
{
<option value="-1">&lt;Select Folder&gt;</option>
}
@foreach (Folder folder in folders)
{
if (folder.FolderId == folderid)
{
<option value="@(folder.FolderId)" selected>@(new string('-', folder.Level * 2))@(folder.Name)</option>
}
else
{
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
}
}
</select>
@if (showfiles)
{
<select class="form-control" @onchange="(e => FileChanged(e))">
<option value="-1">&lt;Select File&gt;</option>
@foreach (File file in files)
{
if (file.FileId == fileid)
{
<option value="@(file.FileId)" selected>@(file.Name)</option>
}
else
{
<option value="@(file.FileId)">@(file.Name)</option>
}
}
</select>
}
@if (haseditpermission)
{
<div>
@if (uploadmultiple)
{
<input type="file" id="@fileinputid" name="file" accept="@filter" multiple />
}
else
{
<input type="file" id="@fileinputid" name="file" accept="@filter" />
}
<span id="@progressinfoid"></span> <progress id="@progressbarid" style="visibility: hidden;"></progress>
@if (showfiles && GetFileId() != -1)
{
<button type="button" class="btn btn-danger float-right" @onclick="DeleteFile">Delete</button>
}
<button type="button" class="btn btn-success float-right" @onclick="UploadFile">Upload</button>
</div>
@((MarkupString)@message)
}
}
@code {
[Parameter]
public string Folder { get; set; } // optional - for setting a specific folder by default
[Parameter]
public string FolderId { get; set; } // optional - for setting a specific folderid by default
[Parameter]
public string ShowFiles { get; set; } // optional - for indicating whether a list of files should be displayed - default is true
[Parameter]
public string FileId { get; set; } // optional - for setting a specific file by default
[Parameter]
public string Filter { get; set; } // optional - comma delimited list of file types that can be selected or uploaded ie. ".jpg,.gif"
[Parameter]
public string UploadMultiple { get; set; } // optional - enable multiple file uploads - default false
string id;
List<Folder> folders;
int folderid = -1;
List<File> files = new List<File>();
int fileid = -1;
bool showfiles = true;
string fileinputid = "";
string progressinfoid = "";
string progressbarid = "";
string filter = "*";
bool uploadmultiple = false;
bool haseditpermission = false;
string message = "";
protected override async Task OnInitializedAsync()
{
if (!string.IsNullOrEmpty(Folder))
{
folders = new List<Folder>();
folders.Add(new Folder { FolderId = -1, Name = Folder });
folderid = -1;
}
else
{
folders = await FolderService.GetFoldersAsync(ModuleState.SiteId);
if (!string.IsNullOrEmpty(FolderId))
{
folderid = int.Parse(FolderId);
}
}
if (!string.IsNullOrEmpty(FileId))
{
fileid = int.Parse(FileId);
if (fileid != -1)
{
File file = await FileService.GetFileAsync(int.Parse(FileId));
if (file != null)
{
folderid = file.FolderId;
}
}
}
if (!string.IsNullOrEmpty(ShowFiles))
{
showfiles = bool.Parse(ShowFiles);
}
if (!string.IsNullOrEmpty(Filter))
{
filter = Filter;
}
await GetFiles();
// create unique id for component
id = Guid.NewGuid().ToString("N");
fileinputid = id + "FileInput";
progressinfoid = id + "ProgressInfo";
progressbarid = id + "ProgressBar";
if (!string.IsNullOrEmpty(UploadMultiple))
{
uploadmultiple = bool.Parse(UploadMultiple);
}
}
private async Task GetFiles()
{
haseditpermission = false;
if (!string.IsNullOrEmpty(Folder))
{
haseditpermission = UserSecurity.IsAuthorized(PageState.User, Constants.HostRole);
files = await FileService.GetFilesAsync(Folder);
}
else
{
Folder folder = folders.Where(item => item.FolderId == folderid).FirstOrDefault();
if (folder != null)
{
haseditpermission = UserSecurity.IsAuthorized(PageState.User, "Edit", folder.Permissions);
files = await FileService.GetFilesAsync(folderid);
}
else
{
haseditpermission = false;
files = new List<File>();
}
}
if (filter != "*")
{
List<File> filtered = new List<File>();
foreach (File file in files)
{
if (filter.ToUpper().IndexOf("." + file.Extension.ToUpper()) != -1)
{
filtered.Add(file);
}
}
files = filtered;
}
}
private async void FolderChanged(ChangeEventArgs e)
{
message = "";
try
{
folderid = int.Parse((string)e.Value);
await GetFiles();
fileid = -1;
StateHasChanged();
}
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>";
}
}
private void FileChanged(ChangeEventArgs e)
{
message = "";
fileid = int.Parse((string)e.Value);
StateHasChanged();
}
private async Task UploadFile()
{
var interop = new Interop(jsRuntime);
string[] upload = await interop.GetFiles(fileinputid);
if (upload.Length > 0)
{
try
{
string result;
if (!string.IsNullOrEmpty(Folder))
{
result = await FileService.UploadFilesAsync(Folder, upload, id);
}
else
{
result = await FileService.UploadFilesAsync(folderid, upload, id);
}
if (result == "")
{
await logger.LogInformation("File Upload Succeeded {Files}", upload);
message = "<br /><div class=\"alert alert-success\" role=\"alert\">File Upload Succeeded</div>";
await GetFiles();
if (upload.Length == 1)
{
File file = files.Where(item => item.Name == upload[0]).FirstOrDefault();
if (file != null)
{
fileid = file.FileId;
}
}
StateHasChanged();
}
else
{
await logger.LogError("File Upload Failed For {Files}", result.Replace(",", ", "));
message = "<br /><div class=\"alert alert-danger\" role=\"alert\">File Upload Failed</div>";
}
}
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>";
}
}
else
{
message = "<br /><div class=\"alert alert-warning\" role=\"alert\">You Have Not Selected A File To Upload</div>";
}
}
private async Task DeleteFile()
{
message = "";
try
{
await FileService.DeleteFileAsync(fileid);
await logger.LogInformation("File Deleted {File}", fileid);
message = "<br /><div class=\"alert alert-success\" role=\"alert\">File Deleted</div>";
await GetFiles();
fileid = -1;
StateHasChanged();
}
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>";
}
}
public int GetFileId()
{
return fileid;
}
}

View File

@ -1,54 +0,0 @@
@namespace Oqtane.Modules.Controls
@inject IJSRuntime jsRuntime
@if (multiple)
{
<input type="file" id="@fileid" name="file" accept="@filter" value="@files" multiple />
}
else
{
<input type="file" id="@fileid" name="file" accept="@filter" value="@files" />
}
<span id="@progressinfoid"></span> <progress id="@progressbarid" style="visibility: hidden;"></progress>
@code {
[Parameter]
public string Name { get; set; } // optional - can be used for managing multiple file upload controls on a page
[Parameter]
public string Filter { get; set; } // optional - for restricting types of files that can be selected
[Parameter]
public string Multiple { get; set; } // optional - enable multiple file uploads
string fileid = "";
string progressinfoid = "";
string progressbarid = "";
string filter = "*";
string files = "";
bool multiple = false;
protected override void OnInitialized()
{
fileid = Name + "FileInput";
progressinfoid = Name + "ProgressInfo";
progressbarid = Name + "ProgressBar";
if (!string.IsNullOrEmpty(Filter))
{
filter = Filter;
}
if (!string.IsNullOrEmpty(Multiple))
{
multiple = bool.Parse(Multiple);
}
}
public async Task<string[]> GetFiles()
{
var interop = new Interop(jsRuntime);
string[] files = await interop.GetFiles(fileid);
return files;
}
}

View File

@ -107,22 +107,25 @@
{
permissions.Add(new PermissionString { PermissionName = permissionname, Permissions = "" });
}
foreach (PermissionString permissionstring in UserSecurity.GetPermissionStrings(Permissions))
if (Permissions != "")
{
if (permissions.Find(item => item.PermissionName == permissionstring.PermissionName) != null)
foreach (PermissionString permissionstring in UserSecurity.GetPermissionStrings(Permissions))
{
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))
if (permissions.Find(item => item.PermissionName == permissionstring.PermissionName) != null)
{
if (user.Contains("]"))
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))
{
int userid = int.Parse(user.Substring(0, user.IndexOf("]")));
if (users.Where(item => item.UserId == userid).FirstOrDefault() == null)
if (user.Contains("]"))
{
users.Add(await UserService.GetUserAsync(userid, ModuleState.SiteId));
int userid = int.Parse(user.Substring(0, user.IndexOf("]")));
if (users.Where(item => item.UserId == userid).FirstOrDefault() == null)
{
users.Add(await UserService.GetUserAsync(userid, ModuleState.SiteId));
}
}
}
}

View File

@ -109,6 +109,17 @@ namespace Oqtane.Modules
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
}
public string ContentUrl(int fileid)
{
string apiurl = PageState.Uri.Scheme + "://" + PageState.Alias.Name + "/";
if (PageState.Alias.Path == "")
{
apiurl += "~/";
}
apiurl += "api/File/Download/" + fileid.ToString();
return apiurl;
}
// user feedback methods
public void AddModuleMessage(string message, MessageType type)
{

View File

@ -1,9 +1,11 @@
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using Oqtane.Models;
using Oqtane.Shared;
namespace Oqtane.Services
@ -28,17 +30,52 @@ namespace Oqtane.Services
get { return CreateApiUrl(sitestate.Alias, NavigationManager.Uri, "File"); }
}
public async Task<List<string>> GetFilesAsync(string Folder)
public async Task<List<File>> GetFilesAsync(int FolderId)
{
return await http.GetJsonAsync<List<string>>(apiurl + "?folder=" + Folder);
return await GetFilesAsync(FolderId.ToString());
}
public async Task<string> UploadFilesAsync(string Folder, string[] Files, string FileUploadName)
public async Task<List<File>> GetFilesAsync(string Folder)
{
return await http.GetJsonAsync<List<File>>(apiurl + "?folder=" + Folder);
}
public async Task<File> GetFileAsync(int FileId)
{
return await http.GetJsonAsync<File>(apiurl + "/" + FileId.ToString());
}
public async Task<File> AddFileAsync(File File)
{
return await http.PostJsonAsync<File>(apiurl, File);
}
public async Task<File> UpdateFileAsync(File File)
{
return await http.PutJsonAsync<File>(apiurl + "/" + File.FileId.ToString(), File);
}
public async Task DeleteFileAsync(int FileId)
{
await http.DeleteAsync(apiurl + "/" + FileId.ToString());
}
public async Task<File> UploadFileAsync(string Url, int FolderId)
{
return await http.GetJsonAsync<File>(apiurl + "/upload?url=" + WebUtility.UrlEncode(Url) + "&folderid=" + FolderId.ToString());
}
public async Task<string> UploadFilesAsync(int FolderId, string[] Files, string Id)
{
return await UploadFilesAsync(FolderId.ToString(), Files, Id);
}
public async Task<string> UploadFilesAsync(string Folder, string[] Files, string Id)
{
string result = "";
var interop = new Interop(jsRuntime);
await interop.UploadFiles(apiurl + "/upload", Folder, FileUploadName);
await interop.UploadFiles(apiurl + "/upload", Folder, Id);
// uploading files is asynchronous so we need to wait for the upload to complete
bool success = false;
@ -48,13 +85,13 @@ namespace Oqtane.Services
Thread.Sleep(2000); // wait 2 seconds
result = "";
List<string> files = await GetFilesAsync(Folder);
List<File> files = await GetFilesAsync(Folder);
if (files.Count > 0)
{
success = true;
foreach (string file in Files)
{
if (!files.Contains(file))
if (!files.Exists(item => item.Name == file))
{
success = false;
result += file + ",";
@ -71,9 +108,9 @@ namespace Oqtane.Services
return result;
}
public async Task DeleteFileAsync(string Folder, string File)
public async Task<byte[]> DownloadFileAsync(int FileId)
{
await http.DeleteAsync(apiurl + "?folder=" + Folder + "&file=" + File);
return await http.GetByteArrayAsync(apiurl + "/download/" + FileId.ToString());
}
}
}

View File

@ -6,8 +6,16 @@ namespace Oqtane.Services
{
public interface IFileService
{
Task<List<string>> GetFilesAsync(string Folder);
Task<List<File>> GetFilesAsync(int FolderId);
Task<List<File>> GetFilesAsync(string Folder);
Task<File> GetFileAsync(int FileId);
Task<File> AddFileAsync(File File);
Task<File> UpdateFileAsync(File File);
Task DeleteFileAsync(int FileId);
Task<File> UploadFileAsync(string Url, int FolderId);
Task<string> UploadFilesAsync(int FolderId, string[] Files, string FileUploadName);
Task<string> UploadFilesAsync(string Folder, string[] Files, string FileUploadName);
Task DeleteFileAsync(string Folder, string File);
Task<byte[]> DownloadFileAsync(int FileId);
}
}

View File

@ -98,7 +98,7 @@
</tr>
<tr>
<td>
<label for="Title" class="control-label" style="font-weight: bold">Confirm Password: </label>
<label for="Title" class="control-label" style="font-weight: bold">Confirm: </label>
</td>
<td>
<input type="password" class="form-control" @bind="@ConfirmPassword" />
@ -142,7 +142,7 @@
private void SetIntegratedSecurity(ChangeEventArgs e)
{
if (Convert.ToBoolean(e.Value))
if (Convert.ToBoolean((string)e.Value))
{
IntegratedSecurityDisplay = "display: none;";
}
@ -183,7 +183,7 @@
Site site = new Site();
site.TenantId = -1; // will be populated on server
site.Name = "Default Site";
site.Logo = "oqtane.png";
site.LogoFileId = null;
site.DefaultThemeType = Constants.DefaultTheme;
site.DefaultLayoutType = Constants.DefaultLayout;
site.DefaultContainerType = Constants.DefaultContainer;

View File

@ -87,13 +87,13 @@ namespace Oqtane.Shared
}
}
public ValueTask<string[]> GetFiles(string name)
public ValueTask<string[]> GetFiles(string id)
{
try
{
return jsRuntime.InvokeAsync<string[]>(
"interop.getFiles",
name);
id);
}
catch
{
@ -101,13 +101,13 @@ namespace Oqtane.Shared
}
}
public Task UploadFiles(string posturl, string folder, string name)
public Task UploadFiles(string posturl, string folder, string id)
{
try
{
jsRuntime.InvokeAsync<string>(
"interop.uploadFiles",
posturl, folder, name);
posturl, folder, id);
return Task.CompletedTask;
}
catch

View File

@ -51,12 +51,13 @@ namespace Oqtane.Client
services.AddScoped<IRoleService, RoleService>();
services.AddScoped<IUserRoleService, UserRoleService>();
services.AddScoped<ISettingService, SettingService>();
services.AddScoped<IFileService, FileService>();
services.AddScoped<IPackageService, PackageService>();
services.AddScoped<ILogService, LogService>();
services.AddScoped<IJobService, JobService>();
services.AddScoped<IJobLogService, JobLogService>();
services.AddScoped<INotificationService, NotificationService>();
services.AddScoped<IFolderService, FolderService>();
services.AddScoped<IFileService, FileService>();
// dynamically register module contexts and repository services
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();

View File

@ -263,7 +263,7 @@
}
else
{
moduledefinitions = PageState.ModuleDefinitions.Where(item => item.Categories.Contains(e.Value.ToString())).ToList();
moduledefinitions = PageState.ModuleDefinitions.Where(item => item.Categories.Contains(category)).ToList();
}
moduledefinitionname = "-";
StateHasChanged();

View File

@ -9,10 +9,10 @@
protected override void OnParametersSet()
{
if (PageState.Site.Logo != "")
if (PageState.Site.LogoFileId != null)
{
Uri uri = new Uri(NavigationManager.Uri);
logo = "<a href=\"" + uri.Scheme + "://" + uri.Authority + "\"><img src=\"" + uri.Scheme + "://" + uri.Authority + "/" + PageState.Site.SiteRootPath + PageState.Site.Logo + "\" alt=\"" + PageState.Site.Name + "\"/></a>";
logo = "<a href=\"" + uri.Scheme + "://" + uri.Authority + "\"><img src=\"" + ContentUrl(PageState.Site.LogoFileId.Value) + "\" alt=\"" + PageState.Site.Name + "\"/></a>";
}
}
}

View File

@ -52,5 +52,16 @@ namespace Oqtane.Themes
{
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
}
public string ContentUrl(int fileid)
{
string apiurl = PageState.Uri.Scheme + "://" + PageState.Alias.Name + "/";
if (PageState.Alias.Path == "")
{
apiurl += "~/";
}
apiurl += "api/File/Download/" + fileid.ToString();
return apiurl;
}
}
}

View File

@ -62,9 +62,9 @@ window.interop = {
document.body.appendChild(form);
form.submit();
},
getFiles: function (name) {
getFiles: function (id) {
var files = [];
var fileinput = document.getElementById(name);
var fileinput = document.getElementById(id);
if (fileinput !== null) {
for (var i = 0; i < fileinput.files.length; i++) {
files.push(fileinput.files[i].name);
@ -72,10 +72,10 @@ window.interop = {
}
return files;
},
uploadFiles: function (posturl, folder, name) {
var files = document.getElementById(name + 'FileInput').files;
var progressinfo = document.getElementById(name + 'ProgressInfo');
var progressbar = document.getElementById(name + 'ProgressBar');
uploadFiles: function (posturl, folder, id) {
var files = document.getElementById(id + 'FileInput').files;
var progressinfo = document.getElementById(id + 'ProgressInfo');
var progressbar = document.getElementById(id + 'ProgressBar');
var filename = '';
for (var i = 0; i < files.length; i++) {

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -3,12 +3,16 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Oqtane.Infrastructure;
using Oqtane.Repository;
using Oqtane.Models;
using Oqtane.Shared;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Oqtane.Security;
using System.Linq;
namespace Oqtane.Controllers
{
@ -16,53 +20,163 @@ namespace Oqtane.Controllers
public class FileController : Controller
{
private readonly IWebHostEnvironment environment;
private readonly IFileRepository Files;
private readonly IFolderRepository Folders;
private readonly IUserPermissions UserPermissions;
private readonly ITenantResolver Tenants;
private readonly ILogManager logger;
private readonly string WhiteList = "jpg,jpeg,jpe,gif,bmp,png,mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg";
public FileController(IWebHostEnvironment environment, ILogManager logger)
public FileController(IWebHostEnvironment environment, IFileRepository Files, IFolderRepository Folders, IUserPermissions UserPermissions, ITenantResolver Tenants, ILogManager logger)
{
this.environment = environment;
this.Files = Files;
this.Folders = Folders;
this.UserPermissions = UserPermissions;
this.Tenants = Tenants;
this.logger = logger;
}
// GET: api/<controller>?folder=x
[HttpGet]
public IEnumerable<string> Get(string folder)
public IEnumerable<Models.File> Get(string folder)
{
List<string> files = new List<string>();
folder = GetFolder(folder);
if (Directory.Exists(folder))
List<Models.File> files = new List<Models.File>();
int folderid;
if (int.TryParse(folder, out folderid))
{
foreach (string file in Directory.GetFiles(folder))
Folder Folder = Folders.GetFolder(folderid);
if (Folder != null && UserPermissions.IsAuthorized(User, "Browse", Folder.Permissions))
{
files.Add(Path.GetFileName(file));
files = Files.GetFiles(folderid).ToList();
}
}
else
{
if (User.IsInRole(Constants.HostRole))
{
folder = GetFolderPath(folder);
if (Directory.Exists(folder))
{
foreach (string file in Directory.GetFiles(folder))
{
files.Add(new Models.File { Name = Path.GetFileName(file), Extension = Path.GetExtension(file).Replace(".","") });
}
}
}
}
return files;
}
// GET api/<controller>/5
[HttpGet("{id}")]
public Models.File Get(int id)
{
return Files.GetFile(id);
}
// PUT api/<controller>/5
[HttpPut("{id}")]
[Authorize(Roles = Constants.RegisteredRole)]
public Models.File Put(int id, [FromBody] Models.File File)
{
if (ModelState.IsValid && UserPermissions.IsAuthorized(User, "Folder", File.Folder.FolderId, "Edit"))
{
File = Files.UpdateFile(File);
logger.Log(LogLevel.Information, this, LogFunction.Update, "File Updated {File}", File);
}
return File;
}
// DELETE api/<controller>/5
[HttpDelete("{id}")]
[Authorize(Roles = Constants.RegisteredRole)]
public void Delete(int id)
{
Models.File File = Files.GetFile(id);
if (UserPermissions.IsAuthorized(User, "Folder", File.Folder.FolderId, "Edit"))
{
Files.DeleteFile(id);
string filepath = Path.Combine(GetFolderPath(File.Folder) + File.Name);
if (System.IO.File.Exists(filepath))
{
System.IO.File.Delete(filepath);
}
logger.Log(LogLevel.Information, this, LogFunction.Delete, "File Deleted {File}", File);
}
}
// GET api/<controller>/upload?url=x&folderid=y
[HttpGet("upload")]
public Models.File UploadFile(string url, string folderid)
{
Models.File file = null;
Folder folder = Folders.GetFolder(int.Parse(folderid));
if (folder != null && UserPermissions.IsAuthorized(User, "Edit", folder.Permissions))
{
string folderpath = GetFolderPath(folder);
CreateDirectory(folderpath);
string filename = url.Substring(url.LastIndexOf("/") + 1);
try
{
var client = new System.Net.WebClient();
client.DownloadFile(url, folderpath + filename);
FileInfo fileinfo = new FileInfo(folderpath + filename);
file = Files.AddFile(new Models.File { Name = filename, FolderId = folder.FolderId, Extension = fileinfo.Extension.Replace(".",""), Size = (int)fileinfo.Length });
}
catch
{
logger.Log(LogLevel.Error, this, LogFunction.Create, "File Could Not Be Downloaded From Url {Url}", url);
}
}
return file;
}
// POST api/<controller>/upload
[HttpPost("upload")]
[Authorize(Roles = Constants.AdminRole)]
public async Task UploadFile(string folder, IFormFile file)
{
if (file.Length > 0)
{
folder = GetFolder(folder);
if (!Directory.Exists(folder))
string folderpath = "";
int folderid = -1;
if (int.TryParse(folder, out folderid))
{
Directory.CreateDirectory(folder);
Folder Folder = Folders.GetFolder(folderid);
if (Folder != null && UserPermissions.IsAuthorized(User, "Edit", Folder.Permissions))
{
folderpath = GetFolderPath(Folder);
}
}
using (var stream = new FileStream(Path.Combine(folder, file.FileName), FileMode.Create))
else
{
await file.CopyToAsync(stream);
if (User.IsInRole(Constants.HostRole))
{
folderpath = GetFolderPath(folder);
}
}
if (folderpath != "")
{
CreateDirectory(folderpath);
using (var stream = new FileStream(Path.Combine(folderpath, file.FileName), FileMode.Create))
{
await file.CopyToAsync(stream);
}
string upload = await MergeFile(folderpath, file.FileName);
if (upload != "" && folderid != -1)
{
FileInfo fileinfo = new FileInfo(folderpath + upload);
Files.AddFile(new Models.File { Name = upload, FolderId = folderid, Extension = fileinfo.Extension.Replace(".", ""), Size = (int)fileinfo.Length });
}
}
await MergeFile(folder, file.FileName);
}
}
private async Task MergeFile(string folder, string filename)
private async Task<string> MergeFile(string folder, string filename)
{
string merged = "";
// parse the filename which is in the format of filename.ext.part_x_y
string token = ".part_";
string parts = Path.GetExtension(filename).Replace(token, ""); // returns "x_y"
@ -112,6 +226,7 @@ namespace Oqtane.Controllers
System.IO.File.Move(Path.Combine(folder, filename + ".tmp"), Path.Combine(folder, filename));
logger.Log(LogLevel.Information, this, LogFunction.Create, "File Uploaded {File}", Path.Combine(folder, filename));
}
merged = filename;
}
}
@ -125,6 +240,8 @@ namespace Oqtane.Controllers
System.IO.File.Delete(filepart);
}
}
return merged;
}
private bool CanAccessFiles(string[] files)
@ -164,24 +281,47 @@ namespace Oqtane.Controllers
return canaccess;
}
// DELETE api/<controller>/?folder=x&file=y
[HttpDelete]
[Authorize(Roles = Constants.AdminRole)]
public void Delete(string folder, string file)
// GET api/<controller>/download/5
[HttpGet("download/{id}")]
public IActionResult Download(int id)
{
file = Path.Combine(GetFolder(folder) + file);
if (System.IO.File.Exists(file))
Models.File file = Files.GetFile(id);
if (file != null && UserPermissions.IsAuthorized(User, "View", file.Folder.Permissions))
{
System.IO.File.Delete(file);
logger.Log(LogLevel.Information, this, LogFunction.Delete, "File Deleted {File}", file);
byte[] filebytes = System.IO.File.ReadAllBytes(GetFolderPath(file.Folder) + file.Name);
return File(filebytes, "application/octet-stream", file.Name);
}
else
{
return NotFound();
}
}
private string GetFolder(string folder)
private string GetFolderPath(Folder folder)
{
return environment.ContentRootPath + "\\Content\\Tenants\\" + Tenants.GetTenant().TenantId.ToString() + "\\Sites\\" + folder.SiteId.ToString() + "\\" + folder.Path;
}
private string GetFolderPath(string folder)
{
folder = folder.Replace("/", "\\");
if (folder.StartsWith("\\")) folder = folder.Substring(1);
return Path.Combine(environment.WebRootPath, folder);
}
private void CreateDirectory(string folderpath)
{
if (!Directory.Exists(folderpath))
{
string path = "";
string[] folders = folderpath.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string folder in folders)
{
path += folder + "\\";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
}
}
}
}

View File

@ -52,6 +52,12 @@ namespace Oqtane.Controllers
{
if (ModelState.IsValid && UserPermissions.IsAuthorized(User, "Edit", Folder.Permissions))
{
Folder.Path = "";
if (string.IsNullOrEmpty(Folder.Path) && Folder.ParentId != null)
{
Folder parent = Folders.GetFolder(Folder.ParentId.Value);
Folder.Path = parent.Path + Folder.Name + "\\";
}
Folder = Folders.AddFolder(Folder);
logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Added {Folder}", Folder);
}
@ -65,6 +71,12 @@ namespace Oqtane.Controllers
{
if (ModelState.IsValid && UserPermissions.IsAuthorized(User, "Folder", Folder.FolderId, "Edit"))
{
Folder.Path = "";
if (string.IsNullOrEmpty(Folder.Path) && Folder.ParentId != null)
{
Folder parent = Folders.GetFolder(Folder.ParentId.Value);
Folder.Path = parent.Path + Folder.Name + "\\";
}
Folder = Folders.UpdateFolder(Folder);
logger.Log(LogLevel.Information, this, LogFunction.Update, "Folder Updated {Folder}", Folder);
}

View File

@ -62,11 +62,6 @@ namespace Oqtane.Controllers
if (authorized)
{
Site = Sites.AddSite(Site);
string folder = environment.WebRootPath + "\\Tenants\\" + Tenants.GetTenant().TenantId.ToString() + "\\Sites\\" + Site.SiteId.ToString();
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
logger.Log(LogLevel.Information, this, LogFunction.Create, "Site Added {Site}", Site);
}
}

View File

@ -26,9 +26,10 @@ namespace Oqtane.Controllers
private readonly SignInManager<IdentityUser> IdentitySignInManager;
private readonly ITenantResolver Tenants;
private readonly INotificationRepository Notifications;
private readonly IFolderRepository Folders;
private readonly ILogManager logger;
public UserController(IUserRepository Users, IRoleRepository Roles, IUserRoleRepository UserRoles, UserManager<IdentityUser> IdentityUserManager, SignInManager<IdentityUser> IdentitySignInManager, ITenantResolver Tenants, INotificationRepository Notifications, ILogManager logger)
public UserController(IUserRepository Users, IRoleRepository Roles, IUserRoleRepository UserRoles, UserManager<IdentityUser> IdentityUserManager, SignInManager<IdentityUser> IdentitySignInManager, ITenantResolver Tenants, INotificationRepository Notifications, IFolderRepository Folders, ILogManager logger)
{
this.Users = Users;
this.Roles = Roles;
@ -36,12 +37,14 @@ namespace Oqtane.Controllers
this.IdentityUserManager = IdentityUserManager;
this.IdentitySignInManager = IdentitySignInManager;
this.Tenants = Tenants;
this.Folders = Folders;
this.Notifications = Notifications;
this.logger = logger;
}
// GET: api/<controller>?siteid=x
[HttpGet]
[Authorize(Roles = Constants.AdminRole)]
public IEnumerable<User> Get()
{
return Users.GetUsers();
@ -98,6 +101,8 @@ namespace Oqtane.Controllers
var result = await IdentityUserManager.CreateAsync(identityuser, User.Password);
if (result.Succeeded)
{
User.LastLoginOn = null;
User.LastIPAddress = "";
user = Users.AddUser(User);
if (!verified)
{
@ -128,6 +133,14 @@ namespace Oqtane.Controllers
userrole.ExpiryDate = null;
UserRoles.AddUserRole(userrole);
}
// add folder for user
Folder folder = Folders.GetFolder(User.SiteId, "Users\\");
if (folder != null)
{
Folders.AddFolder(new Folder { SiteId = folder.SiteId, ParentId = folder.FolderId, Name = "My Folder", Path = folder.Path + user.UserId.ToString() + "\\", Order = 1, IsSystem = true,
Permissions = "[{\"PermissionName\":\"Browse\",\"Permissions\":\"[" + user.UserId.ToString() + "]\"},{\"PermissionName\":\"View\",\"Permissions\":\"All Users\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"[" + user.UserId.ToString() + "]\"}]" });
}
}
}
else
@ -222,6 +235,9 @@ namespace Oqtane.Controllers
if (identityuser.EmailConfirmed)
{
user.IsAuthenticated = true;
user.LastLoginOn = DateTime.Now;
user.LastIPAddress = HttpContext.Connection.RemoteIpAddress.ToString();
Users.UpdateUser(user);
logger.Log(LogLevel.Information, this, LogFunction.Security, "User Login Successful {Username}", User.Username);
if (SetCookie)
{

View File

@ -18,8 +18,8 @@ namespace Oqtane.Repository
public IEnumerable<File> GetFiles(int FolderId)
{
IEnumerable<Permission> permissions = Permissions.GetPermissions("Folder", FolderId);
IEnumerable<File> files = db.File.Where(item => item.FolderId == FolderId);
IEnumerable<Permission> permissions = Permissions.GetPermissions("Folder", FolderId).ToList();
IEnumerable<File> files = db.File.Where(item => item.FolderId == FolderId).Include(item => item.Folder);
foreach (File file in files)
{
file.Folder.Permissions = Permissions.EncodePermissions(FolderId, permissions);
@ -43,10 +43,10 @@ namespace Oqtane.Repository
public File GetFile(int FileId)
{
File file = db.File.Find(FileId);
File file = db.File.Where(item => item.FileId == FileId).Include(item => item.Folder).FirstOrDefault();
if (file != null)
{
IEnumerable<Permission> permissions = Permissions.GetPermissions("Folder", file.FolderId);
IEnumerable<Permission> permissions = Permissions.GetPermissions("Folder", file.FolderId).ToList();
file.Folder.Permissions = Permissions.EncodePermissions(file.FolderId, permissions);
}
return file;

View File

@ -53,7 +53,18 @@ namespace Oqtane.Repository
Folder folder = db.Folder.Find(FolderId);
if (folder != null)
{
IEnumerable<Permission> permissions = Permissions.GetPermissions("Folder", folder.FolderId);
IEnumerable<Permission> permissions = Permissions.GetPermissions("Folder", folder.FolderId).ToList();
folder.Permissions = Permissions.EncodePermissions(folder.FolderId, permissions);
}
return folder;
}
public Folder GetFolder(int SiteId, string Path)
{
Folder folder = db.Folder.Where(item => item.SiteId == SiteId && item.Path == Path).FirstOrDefault();
if (folder != null)
{
IEnumerable<Permission> permissions = Permissions.GetPermissions("Folder", folder.FolderId).ToList();
folder.Permissions = Permissions.EncodePermissions(folder.FolderId, permissions);
}
return folder;

View File

@ -10,6 +10,7 @@ namespace Oqtane.Repository
Folder AddFolder(Folder Folder);
Folder UpdateFolder(Folder Folder);
Folder GetFolder(int FolderId);
Folder GetFolder(int SiteId, string Path);
void DeleteFolder(int FolderId);
}
}

View File

@ -3,21 +3,28 @@ using System.Linq;
using Oqtane.Models;
using Microsoft.EntityFrameworkCore;
using System;
using Microsoft.Extensions.Caching.Memory;
namespace Oqtane.Repository
{
public class JobRepository : IJobRepository
{
private MasterDBContext db;
private readonly IMemoryCache _cache;
public JobRepository(MasterDBContext context)
public JobRepository(MasterDBContext context, IMemoryCache cache)
{
db = context;
_cache = cache;
}
public IEnumerable<Job> GetJobs()
{
return db.Job.ToList();
return _cache.GetOrCreate("jobs", entry =>
{
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
return db.Job.ToList();
});
}
public Job AddJob(Job Job)

View File

@ -56,7 +56,7 @@ namespace Oqtane.Repository
.SingleOrDefault(item => item.PageModuleId == PageModuleId);
if (pagemodule != null)
{
IEnumerable<Permission> permissions = Permissions.GetPermissions("Module", pagemodule.ModuleId);
IEnumerable<Permission> permissions = Permissions.GetPermissions("Module", pagemodule.ModuleId).ToList();
pagemodule.Module.Permissions = Permissions.EncodePermissions(pagemodule.ModuleId, permissions);
}
return pagemodule;
@ -68,7 +68,7 @@ namespace Oqtane.Repository
.SingleOrDefault(item => item.PageId == PageId && item.ModuleId == ModuleId);
if (pagemodule != null)
{
IEnumerable<Permission> permissions = Permissions.GetPermissions("Module", pagemodule.ModuleId);
IEnumerable<Permission> permissions = Permissions.GetPermissions("Module", pagemodule.ModuleId).ToList();
pagemodule.Module.Permissions = Permissions.EncodePermissions(pagemodule.ModuleId, permissions);
}
return pagemodule;

View File

@ -55,7 +55,7 @@ namespace Oqtane.Repository
Page page = db.Page.Find(PageId);
if (page != null)
{
IEnumerable<Permission> permissions = Permissions.GetPermissions("Page", page.PageId);
IEnumerable<Permission> permissions = Permissions.GetPermissions("Page", page.PageId).ToList();
page.Permissions = Permissions.EncodePermissions(page.PageId, permissions);
}
return page;
@ -73,7 +73,7 @@ namespace Oqtane.Repository
}
if (page != null)
{
IEnumerable<Permission> permissions = Permissions.GetPermissions("Page", page.PageId);
IEnumerable<Permission> permissions = Permissions.GetPermissions("Page", page.PageId).ToList();
page.Permissions = Permissions.EncodePermissions(page.PageId, permissions);
}
}

View File

@ -15,6 +15,8 @@ namespace Oqtane.Repository
private readonly TenantDBContext db;
private readonly IRoleRepository RoleRepository;
private readonly IProfileRepository ProfileRepository;
private readonly IFolderRepository FolderRepository;
private readonly IFileRepository FileRepository;
private readonly IPageRepository PageRepository;
private readonly IModuleRepository ModuleRepository;
private readonly IPageModuleRepository PageModuleRepository;
@ -22,11 +24,13 @@ namespace Oqtane.Repository
private readonly IServiceProvider ServiceProvider;
private readonly List<PageTemplate> SiteTemplate;
public SiteRepository(TenantDBContext context, IRoleRepository RoleRepository, IProfileRepository ProfileRepository, IPageRepository PageRepository, IModuleRepository ModuleRepository, IPageModuleRepository PageModuleRepository, IModuleDefinitionRepository ModuleDefinitionRepository, IServiceProvider ServiceProvider)
public SiteRepository(TenantDBContext context, IRoleRepository RoleRepository, IProfileRepository ProfileRepository, IFolderRepository FolderRepository, IFileRepository FileRepository, IPageRepository PageRepository, IModuleRepository ModuleRepository, IPageModuleRepository PageModuleRepository, IModuleDefinitionRepository ModuleDefinitionRepository, IServiceProvider ServiceProvider)
{
db = context;
this.RoleRepository = RoleRepository;
this.ProfileRepository = ProfileRepository;
this.FolderRepository = FolderRepository;
this.FileRepository = FileRepository;
this.PageRepository = PageRepository;
this.ModuleRepository = ModuleRepository;
this.PageModuleRepository = PageModuleRepository;
@ -40,7 +44,7 @@ namespace Oqtane.Repository
Content = "<p><a href=\"https://www.oqtane.org\" target=\"_new\">Oqtane</a> is an open source <b>modular application framework</b> built from the ground up using modern .NET Core technology. It leverages the revolutionary new Blazor component model to create a <b>fully dynamic</b> web development experience which can be executed on a client or server. Whether you are looking for a platform to <b>accelerate your web development</b> efforts, or simply interested in exploring the anatomy of a large-scale Blazor application, Oqtane provides a solid foundation based on proven enterprise architectural principles.</p>" +
"<p align=\"center\"><a href=\"https://www.oqtane.org\" target=\"_new\"><img src=\"oqtane.png\"></a><br /><br /><a class=\"btn btn-primary\" href=\"https://www.oqtane.org/Community\" target=\"_new\">Join Our Community</a>&nbsp;&nbsp;<a class=\"btn btn-primary\" href=\"https://github.com/oqtane/oqtane.framework\" target=\"_new\">Clone Our Repo</a><br /><br /></p>" +
"<p><a href=\"https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor\" target=\"_new\">Blazor</a> is a single-page app framework that lets you build interactive web applications using C# instead of JavaScript. Client-side Blazor relies on WebAssembly, an open web standard that does not require plugins or code transpilation in order to run natively in a web browser. Server-side Blazor uses SignalR to host your application on a web server and provide a responsive and robust debugging experience. Blazor applications works in all modern web browsers, including mobile browsers.</p>" +
"<p>Blazor is a feature of <a href=\"https://dotnet.microsoft.com/apps/aspnet\" target=\"_new\">ASP.NET Core 3.0</a>, the popular cross platform web development framework from Microsoft that extends the <a href=\"https://dotnet.microsoft.com/learn/dotnet/what-is-dotnet\" target=\"_new\" >.NET developer platform</a> with tools and libraries for building web apps.</p>"
"<p>Blazor is a feature of <a href=\"https://dotnet.microsoft.com/apps/aspnet\" target=\"_new\">ASP.NET Core 3</a>, the popular cross platform web development framework from Microsoft that extends the <a href=\"https://dotnet.microsoft.com/learn/dotnet/what-is-dotnet\" target=\"_new\" >.NET developer platform</a> with tools and libraries for building web apps.</p>"
},
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "MIT License", Pane = "Content", ModulePermissions = "[{\"PermissionName\":\"View\",\"Permissions\":\"All Users;Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]",
Content = "<p>Copyright (c) 2019 .NET Foundation</p>" +
@ -168,6 +172,15 @@ namespace Oqtane.Repository
ProfileRepository.AddProfile(new Profile { SiteId = site.SiteId, Name = "PostalCode", Title = "Postal Code", Description = "Postal Code Or Zip Code", Category = "Address", ViewOrder = 7, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false });
ProfileRepository.AddProfile(new Profile { SiteId = site.SiteId, Name = "Phone", Title = "Phone Number", Description = "Phone Number", Category = "Contact", ViewOrder = 8, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false });
Folder folder = FolderRepository.AddFolder(new Folder { SiteId = site.SiteId, ParentId = null, Name = "Root", Path = "", Order = 1, IsSystem = true, Permissions = "[{\"PermissionName\":\"Browse\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"View\",\"Permissions\":\"All Users\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]" });
FolderRepository.AddFolder(new Folder { SiteId = site.SiteId, ParentId = folder.FolderId, Name = "Users", Path = "Users\\", Order = 1, IsSystem = true, Permissions = "[{\"PermissionName\":\"Browse\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"View\",\"Permissions\":\"Administrators\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"Administrators\"}]" });
if (site.Name == "Default Site")
{
File file = FileRepository.AddFile(new File { FolderId = folder.FolderId, Name = "logo.png", Extension = "png", Size = 8192 });
site.LogoFileId = file.FileId;
UpdateSite(site);
}
List<ModuleDefinition> moduledefinitions = ModuleDefinitionRepository.GetModuleDefinitions(site.SiteId).ToList();
foreach (PageTemplate pagetemplate in SiteTemplate)
{

View File

@ -8,7 +8,7 @@ CREATE TABLE [dbo].[Site](
[SiteId] [int] IDENTITY(1,1) NOT NULL,
[TenantId] [int] NOT NULL,
[Name] [nvarchar](200) NOT NULL,
[Logo] [nvarchar](50) NOT NULL,
[LogoFileId] [int] NULL,
[DefaultThemeType] [nvarchar](200) NOT NULL,
[DefaultLayoutType] [nvarchar](200) NOT NULL,
[DefaultContainerType] [nvarchar](200) NOT NULL,
@ -96,6 +96,9 @@ CREATE TABLE [dbo].[User](
[Username] [nvarchar](256) NOT NULL,
[DisplayName] [nvarchar](50) NOT NULL,
[Email] [nvarchar](256) NOT NULL,
[PhotoFileId] [int] NULL,
[LastLoginOn] [datetime] NULL,
[LastIPAddress] [nvarchar](50) NOT NULL,
[CreatedBy] [nvarchar](256) NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[ModifiedBy] [nvarchar](256) NOT NULL,
@ -261,6 +264,7 @@ CREATE TABLE [dbo].[Folder](
[Name] [nvarchar](50) NOT NULL,
[ParentId] [int] NULL,
[Order] [int] NOT NULL,
[IsSystem] [bit] NOT NULL,
[CreatedBy] [nvarchar](256) NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[ModifiedBy] [nvarchar](256) NOT NULL,
@ -278,7 +282,9 @@ GO
CREATE TABLE [dbo].[File](
[FileId] [int] IDENTITY(1,1) NOT NULL,
[FolderId] [int] NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Name] [nvarchar](250) NOT NULL,
[Extension] [nvarchar](50) NOT NULL,
[Size] [int] NOT NULL,
[CreatedBy] [nvarchar](256) NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[ModifiedBy] [nvarchar](256) NOT NULL,

View File

@ -139,7 +139,7 @@ GO
SET IDENTITY_INSERT [dbo].[Job] ON
GO
INSERT [dbo].[Job] ([JobId], [Name], [JobType], [Frequency], [Interval], [StartDate], [EndDate], [IsEnabled], [IsStarted], [IsExecuting], [NextExecution], [RetentionHistory], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn])
VALUES (1, N'Notification Job', N'Oqtane.Infrastructure.NotificationJob, Oqtane.Server', N'm', 1, null, null, 1, 0, 0, null, 10, '', getdate(), '', getdate())
VALUES (1, N'Notification Job', N'Oqtane.Infrastructure.NotificationJob, Oqtane.Server', N'm', 1, null, null, 0, 0, 0, null, 10, '', getdate(), '', getdate())
GO
SET IDENTITY_INSERT [dbo].[Job] OFF
GO

View File

@ -82,6 +82,9 @@ namespace Oqtane.Server
options.AddPolicy("EditPage", policy => policy.Requirements.Add(new PermissionRequirement("Page", "Edit")));
options.AddPolicy("ViewModule", policy => policy.Requirements.Add(new PermissionRequirement("Module", "View")));
options.AddPolicy("EditModule", policy => policy.Requirements.Add(new PermissionRequirement("Module", "Edit")));
options.AddPolicy("ViewFolder", policy => policy.Requirements.Add(new PermissionRequirement("Folder", "View")));
options.AddPolicy("EditFolder", policy => policy.Requirements.Add(new PermissionRequirement("Folder", "Edit")));
options.AddPolicy("ListFolder", policy => policy.Requirements.Add(new PermissionRequirement("Folder", "List")));
});
// register scoped core services
@ -101,12 +104,13 @@ namespace Oqtane.Server
services.AddScoped<IRoleService, RoleService>();
services.AddScoped<IUserRoleService, UserRoleService>();
services.AddScoped<ISettingService, SettingService>();
services.AddScoped<IFileService, FileService>();
services.AddScoped<IPackageService, PackageService>();
services.AddScoped<ILogService, LogService>();
services.AddScoped<IJobService, JobService>();
services.AddScoped<IJobLogService, JobLogService>();
services.AddScoped<INotificationService, NotificationService>();
services.AddScoped<IFolderService, FolderService>();
services.AddScoped<IFileService, FileService>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
@ -181,6 +185,8 @@ namespace Oqtane.Server
services.AddTransient<IJobRepository, JobRepository>();
services.AddTransient<IJobLogRepository, JobLogRepository>();
services.AddTransient<INotificationRepository, NotificationRepository>();
services.AddTransient<IFolderRepository, FolderRepository>();
services.AddTransient<IFileRepository, FileRepository>();
services.AddOqtaneModules();
services.AddOqtaneThemes();
@ -329,6 +335,8 @@ namespace Oqtane.Server
services.AddTransient<IJobRepository, JobRepository>();
services.AddTransient<IJobLogRepository, JobLogRepository>();
services.AddTransient<INotificationRepository, NotificationRepository>();
services.AddTransient<IFolderRepository, FolderRepository>();
services.AddTransient<IFileRepository, FileRepository>();
services.AddOqtaneModules();
services.AddOqtaneThemes();

View File

@ -62,9 +62,9 @@ window.interop = {
document.body.appendChild(form);
form.submit();
},
getFiles: function (name) {
getFiles: function (id) {
var files = [];
var fileinput = document.getElementById(name);
var fileinput = document.getElementById(id);
if (fileinput !== null) {
for (var i = 0; i < fileinput.files.length; i++) {
files.push(fileinput.files[i].name);
@ -72,10 +72,10 @@ window.interop = {
}
return files;
},
uploadFiles: function (posturl, folder, name) {
var files = document.getElementById(name + 'FileInput').files;
var progressinfo = document.getElementById(name + 'ProgressInfo');
var progressbar = document.getElementById(name + 'ProgressBar');
uploadFiles: function (posturl, folder, id) {
var files = document.getElementById(id + 'FileInput').files;
var progressinfo = document.getElementById(id + 'ProgressInfo');
var progressbar = document.getElementById(id + 'ProgressBar');
var filename = '';
for (var i = 0; i < files.length; i++) {

View File

@ -7,6 +7,8 @@ namespace Oqtane.Models
public int FileId { get; set; }
public int FolderId { get; set; }
public string Name { get; set; }
public string Extension { get; set; }
public int Size { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }

View File

@ -11,6 +11,7 @@ namespace Oqtane.Models
public string Name { get; set; }
public string Path { get; set; }
public int Order { get; set; }
public bool IsSystem { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }

View File

@ -8,7 +8,7 @@ namespace Oqtane.Models
public int SiteId { get; set; }
public int TenantId { get; set; }
public string Name { get; set; }
public string Logo { get; set; }
public int? LogoFileId { get; set; }
public string DefaultThemeType { get; set; }
public string DefaultLayoutType { get; set; }
public string DefaultContainerType { get; set; }

View File

@ -9,6 +9,9 @@ namespace Oqtane.Models
public string Username { get; set; }
public string DisplayName { get; set; }
public string Email { get; set; }
public int? PhotoFileId { get; set; }
public DateTime? LastLoginOn { get; set; }
public string LastIPAddress { get; set; }
[NotMapped]
public int SiteId { get; set; }