Support for non-admin commands to be available to non-admin users
This commit is contained in:
parent
e08cfa84bb
commit
7bcbbdb5ce
@ -20,9 +20,10 @@
|
|||||||
*@
|
*@
|
||||||
[Inject] protected IUserSession UserSession { get; set; } = null!;
|
[Inject] protected IUserSession UserSession { get; set; } = null!;
|
||||||
|
|
||||||
public class CommandParams(string name, Action<CommandParams> changed)
|
public class CommandParams(string name, CmdType commandType, Action<CommandParams> changed)
|
||||||
{
|
{
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
public CmdType CommandType { get; } = commandType;
|
||||||
|
|
||||||
public string CommandJson
|
public string CommandJson
|
||||||
{
|
{
|
||||||
@ -227,4 +228,10 @@
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MongoCommandAttribute? GetCommandAttribute() =>
|
||||||
|
GetType().GetCustomAttributes(typeof(MongoCommandAttribute), true)
|
||||||
|
.OfType<MongoCommandAttribute>()
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
public CmdType CommandType => GetCommandAttribute()?.Type ?? CmdType.Admin;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,9 +6,11 @@
|
|||||||
@using System.Reflection
|
@using System.Reflection
|
||||||
@using Rms.Risk.Mango.Components.Commands
|
@using Rms.Risk.Mango.Components.Commands
|
||||||
|
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IUserSession UserSession
|
@inject IUserSession UserSession
|
||||||
@inject IJSRuntime JsRuntime
|
@inject IJSRuntime JsRuntime
|
||||||
|
@inject AuthenticationStateProvider AuthProvider;
|
||||||
|
@inject IAuthorizationService AuthService;
|
||||||
|
|
||||||
@*
|
@*
|
||||||
* dbMango
|
* dbMango
|
||||||
@ -84,7 +86,7 @@
|
|||||||
|
|
||||||
<h3 class="mt-3">Commands</h3>
|
<h3 class="mt-3">Commands</h3>
|
||||||
|
|
||||||
<AuthorizedOnly Policy="AdminAccess" Resource="@UserSession.Database">
|
<AuthorizedOnly Policy="ReadAccess" Resource="@UserSession.Database">
|
||||||
<EditForm EditContext="EditContext">
|
<EditForm EditContext="EditContext">
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -100,10 +102,10 @@
|
|||||||
</EditForm>
|
</EditForm>
|
||||||
|
|
||||||
<TabControl Class="row flex-stack-horizontal px-3" Vertical="true" @bind-ActivePage="SelectedCommand" TabGroupClass="tab-group" PersistAllTabs="true">
|
<TabControl Class="row flex-stack-horizontal px-3" Vertical="true" @bind-ActivePage="SelectedCommand" TabGroupClass="tab-group" PersistAllTabs="true">
|
||||||
@foreach (var (group, controls) in _availableCommands)
|
@foreach (var (group, controls) in _userAvailableCommands)
|
||||||
{
|
{
|
||||||
<TabPage Text="@group" IsSelectable="false"/>
|
<TabPage Text="@group" IsSelectable="false"/>
|
||||||
@foreach (var (name, control) in controls)
|
@foreach (var (name, _, control) in controls)
|
||||||
{
|
{
|
||||||
var parameters = new Dictionary<string, object>()
|
var parameters = new Dictionary<string, object>()
|
||||||
{
|
{
|
||||||
@ -184,7 +186,7 @@
|
|||||||
}
|
}
|
||||||
} = "Statistics";
|
} = "Statistics";
|
||||||
|
|
||||||
private static string[] _groupsOrder =
|
private static readonly string[] _groupsOrder =
|
||||||
[
|
[
|
||||||
"Informational",
|
"Informational",
|
||||||
"Admin",
|
"Admin",
|
||||||
@ -195,23 +197,30 @@
|
|||||||
|
|
||||||
|
|
||||||
private string Timeout { get; set; } = "20";
|
private string Timeout { get; set; } = "20";
|
||||||
private string Error { get; set; } = "";
|
private string Error { get; set; } = "";
|
||||||
|
private bool IsReady { get; set; }
|
||||||
|
|
||||||
private bool IsReady { get; set; }
|
|
||||||
private bool IsReadyToRun => IsReady && CanExecute && !string.IsNullOrWhiteSpace(CommandJson);
|
private bool IsReadyToRun => IsReady && CanExecute && !string.IsNullOrWhiteSpace(CommandJson);
|
||||||
|
|
||||||
private EditContext? _editContext;
|
private EditContext? _editContext;
|
||||||
private EditContext EditContext => _editContext!;
|
private EditContext EditContext => _editContext!;
|
||||||
|
|
||||||
private string CommandName => _commandParams[SelectedCommand].Name;
|
private string CommandName => _commandParams[SelectedCommand].Name;
|
||||||
|
private CmdType CommandType => _commandParams[SelectedCommand].CommandType;
|
||||||
private string CommandJson => _commandParams[SelectedCommand].CommandJson;
|
private string CommandJson => _commandParams[SelectedCommand].CommandJson;
|
||||||
private bool CanExecute => _commandParams[SelectedCommand].CanExecute;
|
private bool CanExecute => _commandParams[SelectedCommand].CanExecute;
|
||||||
private bool NeedConfirmation => _commandParams[SelectedCommand].NeedConfirmation;
|
private bool NeedConfirmation => _commandParams[SelectedCommand].NeedConfirmation;
|
||||||
private CmdBase.CommandParams.DatabaseConnectionType RequiredConnectionType => _commandParams[SelectedCommand].RequiredConnectionType;
|
private CmdBase.CommandParams.DatabaseConnectionType RequiredConnectionType => _commandParams[SelectedCommand].RequiredConnectionType;
|
||||||
|
|
||||||
private static readonly List<(string Group, List<(string Name, Type Control)> Controls)> _availableCommands;
|
private static readonly List<(string Group, List<(string Name, CmdType CommandType, Type Control)> Controls)> _availableCommands;
|
||||||
private Dictionary<string, CmdBase.CommandParams> _commandParams = null!;
|
private List<(string Group, List<(string Name, CmdType CommandType, Type Control)> Controls)> _userAvailableCommands = [];
|
||||||
private readonly Dictionary<string, Shell.ShardProperties> _shardConnectionStrings = [];
|
|
||||||
|
private Dictionary<string, CmdBase.CommandParams> _commandParams = null!;
|
||||||
|
private readonly Dictionary<string, Shell.ShardProperties> _shardConnectionStrings = [];
|
||||||
|
|
||||||
|
private bool _isWrite;
|
||||||
|
private bool _isRead;
|
||||||
|
private bool _isAdmin;
|
||||||
|
|
||||||
private string Shard { get; set; } = "";
|
private string Shard { get; set; } = "";
|
||||||
private IReadOnlyCollection<string> Shards => _shardConnectionStrings.Keys.OrderBy(x => x).ToList();
|
private IReadOnlyCollection<string> Shards => _shardConnectionStrings.Keys.OrderBy(x => x).ToList();
|
||||||
@ -232,7 +241,7 @@
|
|||||||
})
|
})
|
||||||
.Where(x => x.Attr != null)
|
.Where(x => x.Attr != null)
|
||||||
.GroupBy(x => x.Attr!.Group)
|
.GroupBy(x => x.Attr!.Group)
|
||||||
.Select(x => (Group: x.Key, Commands: x.OrderBy(y => y.Attr!.Name).Select(y => (y.Attr!.Name, Control: y.Type) ).ToList()))
|
.Select(x => (Group: x.Key, Commands: x.OrderBy(y => y.Attr!.Name).Select(y => (y.Attr!.Name, CommandType: y.Attr.Type, Control: y.Type) ).ToList()))
|
||||||
.Where(x => _groupsOrder.Contains(x.Group))
|
.Where(x => _groupsOrder.Contains(x.Group))
|
||||||
.OrderBy(x => Array.IndexOf(_groupsOrder, x.Group))
|
.OrderBy(x => Array.IndexOf(_groupsOrder, x.Group))
|
||||||
.ToList()
|
.ToList()
|
||||||
@ -248,7 +257,7 @@
|
|||||||
_commandParams = new(
|
_commandParams = new(
|
||||||
_availableCommands
|
_availableCommands
|
||||||
.SelectMany(x => x.Controls)
|
.SelectMany(x => x.Controls)
|
||||||
.Select(x => new KeyValuePair<string, CmdBase.CommandParams>(x.Name, new (x.Name, OnChanged))
|
.Select(x => new KeyValuePair<string, CmdBase.CommandParams>(x.Name, new (x.Name, x.CommandType, OnChanged))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -258,7 +267,7 @@
|
|||||||
InvokeAsync(StateHasChanged);
|
InvokeAsync(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnAfterRender(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
if (!firstRender)
|
if (!firstRender)
|
||||||
return;
|
return;
|
||||||
@ -280,6 +289,8 @@
|
|||||||
SelectedCollection = CollectionStr;
|
SelectedCollection = CollectionStr;
|
||||||
|
|
||||||
SyncUrl();
|
SyncUrl();
|
||||||
|
await Authorize();
|
||||||
|
SelectAvailableCommands();
|
||||||
|
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
@ -299,6 +310,41 @@
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SelectAvailableCommands()
|
||||||
|
{
|
||||||
|
_userAvailableCommands = _availableCommands
|
||||||
|
.Select(x =>
|
||||||
|
x with {
|
||||||
|
Controls = x.Controls
|
||||||
|
.Where(y =>
|
||||||
|
y.CommandType switch
|
||||||
|
{
|
||||||
|
CmdType.Admin => _isAdmin,
|
||||||
|
CmdType.Read => _isRead,
|
||||||
|
CmdType.Write => _isWrite,
|
||||||
|
_ => false
|
||||||
|
})
|
||||||
|
.ToList()
|
||||||
|
})
|
||||||
|
.Where(x => x.Controls.Count > 0)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Authorize()
|
||||||
|
{
|
||||||
|
var user = (await AuthProvider.GetAuthenticationStateAsync()).User;
|
||||||
|
|
||||||
|
var readTask = AuthService.AuthorizeAsync(user, UserSession.Database, "ReadAccess");
|
||||||
|
var writeTask = AuthService.AuthorizeAsync(user, UserSession.Database, "WriteAccess");
|
||||||
|
var adminTask = AuthService.AuthorizeAsync(user, UserSession.Database, "AdminAccess");
|
||||||
|
|
||||||
|
var results = await Task.WhenAll(readTask, writeTask, adminTask);
|
||||||
|
|
||||||
|
_isRead = results[0].Succeeded;
|
||||||
|
_isWrite = results[1].Succeeded;
|
||||||
|
_isAdmin = results[2].Succeeded;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task LoadCollections()
|
private async Task LoadCollections()
|
||||||
{
|
{
|
||||||
var admin = UserSession.MongoDbAdmin;
|
var admin = UserSession.MongoDbAdmin;
|
||||||
@ -372,7 +418,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ticket = await CanExecuteCommand();
|
var ticket = CommandType == CmdType.Read ? "N/A" : await CanExecuteCommand();
|
||||||
if (string.IsNullOrWhiteSpace(ticket))
|
if (string.IsNullOrWhiteSpace(ticket))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@ -155,7 +155,7 @@
|
|||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
_editContext = new(this);
|
_editContext = new(this);
|
||||||
_commandParams = new("Delete Documents", OnChanged);
|
_commandParams = new("Delete Documents", CmdType.Write, OnChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnChanged(CmdBase.CommandParams arg)
|
private void OnChanged(CmdBase.CommandParams arg)
|
||||||
|
|||||||
@ -155,7 +155,7 @@
|
|||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
_editContext = new(this);
|
_editContext = new(this);
|
||||||
_commandParams = new("Update Documents", OnChanged);
|
_commandParams = new("Update Documents", CmdType.Write, OnChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnChanged(CmdBase.CommandParams arg)
|
private void OnChanged(CmdBase.CommandParams arg)
|
||||||
|
|||||||
@ -96,7 +96,7 @@ public class TempFileStorage : ITempFileStorage, IDisposable
|
|||||||
{
|
{
|
||||||
if ( Directory.Exists( TempFolder ) )
|
if ( Directory.Exists( TempFolder ) )
|
||||||
{
|
{
|
||||||
SafeDeleteFolder( TempFolder );
|
FileUtils.SafeDeleteFolder( TempFolder );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,20 +114,14 @@ public class TempFileStorage : ITempFileStorage, IDisposable
|
|||||||
|
|
||||||
foreach ( var name in outdatedFolders )
|
foreach ( var name in outdatedFolders )
|
||||||
{
|
{
|
||||||
SafeDeleteFolder(name);
|
_log.Debug( $"Deleting temporary Folder=\"{name}\"" );
|
||||||
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
|
FileUtils.SafeDeleteFolder(name);
|
||||||
|
_log.Debug( $"Temporary Folder=\"{name}\" deleted. Elapsed=\"{sw.Elapsed:g}\"" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SafeDeleteFolder(string name)
|
|
||||||
{
|
|
||||||
_log.Debug( $"Deleting temporary Folder=\"{name}\"" );
|
|
||||||
var sw = Stopwatch.StartNew();
|
|
||||||
|
|
||||||
Directory.Delete(name);
|
|
||||||
_log.Debug( $"Temporary Folder=\"{name}\" deleted. Elapsed=\"{sw.Elapsed:g}\"" );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public string TempFolder { get; }
|
public string TempFolder { get; }
|
||||||
public string LocalPersistentFolder { get; }
|
public string LocalPersistentFolder { get; }
|
||||||
|
|
||||||
|
|||||||
@ -66,6 +66,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown2">
|
<div class="dropdown-menu" aria-labelledby="navbarDropdown2">
|
||||||
<NavLink class="dropdown-item" href="#">Change database</NavLink>
|
<NavLink class="dropdown-item" href="#">Change database</NavLink>
|
||||||
|
<NavLink class="dropdown-item" href="admin/commands">Commands</NavLink>
|
||||||
<NavLink class="dropdown-item" href="user/browse">Browse</NavLink>
|
<NavLink class="dropdown-item" href="user/browse">Browse</NavLink>
|
||||||
<NavLink class="dropdown-item" href="user/find">Find</NavLink>
|
<NavLink class="dropdown-item" href="user/find">Find</NavLink>
|
||||||
<NavLink class="dropdown-item" href="user/aggregate">Aggregate</NavLink>
|
<NavLink class="dropdown-item" href="user/aggregate">Aggregate</NavLink>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user