Improved server share permission handling and share ui
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Text.Json;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using MoonCore.Extended.SingleDb;
|
using MoonCore.Extended.SingleDb;
|
||||||
using Moonlight.ApiServer.Configuration;
|
using Moonlight.ApiServer.Configuration;
|
||||||
@@ -40,12 +41,15 @@ public class ServersDataContext : DatabaseContext
|
|||||||
#region Shares
|
#region Shares
|
||||||
|
|
||||||
modelBuilder.Ignore<ServerShareContent>();
|
modelBuilder.Ignore<ServerShareContent>();
|
||||||
|
modelBuilder.Ignore<ServerShareContent.SharePermission>();
|
||||||
|
|
||||||
modelBuilder.Entity<ServerShare>(builder =>
|
modelBuilder.Entity<ServerShare>(builder =>
|
||||||
{
|
{
|
||||||
builder.OwnsOne(x => x.Content, navigationBuilder =>
|
builder.OwnsOne(x => x.Content, navigationBuilder =>
|
||||||
{
|
{
|
||||||
navigationBuilder.ToJson();
|
navigationBuilder.ToJson();
|
||||||
|
|
||||||
|
navigationBuilder.OwnsMany(x => x.Permissions);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using MoonCore.Models;
|
|||||||
using Moonlight.ApiServer.Database.Entities;
|
using Moonlight.ApiServer.Database.Entities;
|
||||||
using MoonlightServers.ApiServer.Database.Entities;
|
using MoonlightServers.ApiServer.Database.Entities;
|
||||||
using MoonlightServers.ApiServer.Extensions;
|
using MoonlightServers.ApiServer.Extensions;
|
||||||
|
using MoonlightServers.ApiServer.Mappers;
|
||||||
using MoonlightServers.ApiServer.Models;
|
using MoonlightServers.ApiServer.Models;
|
||||||
using MoonlightServers.ApiServer.Services;
|
using MoonlightServers.ApiServer.Services;
|
||||||
using MoonlightServers.Shared.Constants;
|
using MoonlightServers.Shared.Constants;
|
||||||
@@ -153,7 +154,7 @@ public class ServersController : Controller
|
|||||||
Share = new()
|
Share = new()
|
||||||
{
|
{
|
||||||
SharedBy = owners.First(y => y.Id == x.Server.OwnerId).Username,
|
SharedBy = owners.First(y => y.Id == x.Server.OwnerId).Username,
|
||||||
Permissions = x.Content.Permissions
|
Permissions = ShareMapper.MapToPermissionLevels(x.Content)
|
||||||
}
|
}
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
|
|
||||||
@@ -223,7 +224,7 @@ public class ServersController : Controller
|
|||||||
response.Share = new()
|
response.Share = new()
|
||||||
{
|
{
|
||||||
SharedBy = owner.Username,
|
SharedBy = owner.Username,
|
||||||
Permissions = authorizationResult.Share.Content.Permissions
|
Permissions = ShareMapper.MapToPermissionLevels(authorizationResult.Share.Content)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ using MoonCore.Extended.Abstractions;
|
|||||||
using MoonCore.Models;
|
using MoonCore.Models;
|
||||||
using Moonlight.ApiServer.Database.Entities;
|
using Moonlight.ApiServer.Database.Entities;
|
||||||
using MoonlightServers.ApiServer.Database.Entities;
|
using MoonlightServers.ApiServer.Database.Entities;
|
||||||
|
using MoonlightServers.ApiServer.Mappers;
|
||||||
|
using MoonlightServers.ApiServer.Models;
|
||||||
using MoonlightServers.ApiServer.Services;
|
using MoonlightServers.ApiServer.Services;
|
||||||
using MoonlightServers.Shared.Constants;
|
using MoonlightServers.Shared.Constants;
|
||||||
using MoonlightServers.Shared.Enums;
|
using MoonlightServers.Shared.Enums;
|
||||||
@@ -68,7 +70,7 @@ public class SharesController : Controller
|
|||||||
{
|
{
|
||||||
Id = x.Id,
|
Id = x.Id,
|
||||||
Username = users.First(y => y.Id == x.UserId).Username,
|
Username = users.First(y => y.Id == x.UserId).Username,
|
||||||
Permissions = x.Content.Permissions
|
Permissions = ShareMapper.MapToPermissionLevels(x.Content)
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
|
|
||||||
return new PagedData<ServerShareResponse>()
|
return new PagedData<ServerShareResponse>()
|
||||||
@@ -104,13 +106,13 @@ public class SharesController : Controller
|
|||||||
{
|
{
|
||||||
Id = share.Id,
|
Id = share.Id,
|
||||||
Username = user.Username,
|
Username = user.Username,
|
||||||
Permissions = share.Content.Permissions
|
Permissions = ShareMapper.MapToPermissionLevels(share.Content)
|
||||||
};
|
};
|
||||||
|
|
||||||
return mappedItem;
|
return mappedItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("")]
|
[HttpPost]
|
||||||
public async Task<ServerShareResponse> Create(
|
public async Task<ServerShareResponse> Create(
|
||||||
[FromRoute] int serverId,
|
[FromRoute] int serverId,
|
||||||
[FromBody] CreateShareRequest request
|
[FromBody] CreateShareRequest request
|
||||||
@@ -128,10 +130,7 @@ public class SharesController : Controller
|
|||||||
var share = new ServerShare()
|
var share = new ServerShare()
|
||||||
{
|
{
|
||||||
Server = server,
|
Server = server,
|
||||||
Content = new()
|
Content = ShareMapper.MapToServerShareContent(request.Permissions),
|
||||||
{
|
|
||||||
Permissions = request.Permissions
|
|
||||||
},
|
|
||||||
CreatedAt = DateTime.UtcNow,
|
CreatedAt = DateTime.UtcNow,
|
||||||
UpdatedAt = DateTime.UtcNow,
|
UpdatedAt = DateTime.UtcNow,
|
||||||
UserId = user.Id
|
UserId = user.Id
|
||||||
@@ -143,7 +142,7 @@ public class SharesController : Controller
|
|||||||
{
|
{
|
||||||
Id = finalShare.Id,
|
Id = finalShare.Id,
|
||||||
Username = user.Username,
|
Username = user.Username,
|
||||||
Permissions = finalShare.Content.Permissions
|
Permissions = ShareMapper.MapToPermissionLevels(finalShare.Content)
|
||||||
};
|
};
|
||||||
|
|
||||||
return mappedItem;
|
return mappedItem;
|
||||||
@@ -165,7 +164,8 @@ public class SharesController : Controller
|
|||||||
if (share == null)
|
if (share == null)
|
||||||
throw new HttpApiException("A share with that id cannot be found", 404);
|
throw new HttpApiException("A share with that id cannot be found", 404);
|
||||||
|
|
||||||
share.Content.Permissions = request.Permissions;
|
share.Content = ShareMapper.MapToServerShareContent(request.Permissions);
|
||||||
|
|
||||||
share.UpdatedAt = DateTime.UtcNow;
|
share.UpdatedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
await ShareRepository.Update(share);
|
await ShareRepository.Update(share);
|
||||||
@@ -181,7 +181,7 @@ public class SharesController : Controller
|
|||||||
{
|
{
|
||||||
Id = share.Id,
|
Id = share.Id,
|
||||||
Username = user.Username,
|
Username = user.Username,
|
||||||
Permissions = share.Content.Permissions
|
Permissions = ShareMapper.MapToPermissionLevels(share.Content)
|
||||||
};
|
};
|
||||||
|
|
||||||
return mappedItem;
|
return mappedItem;
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class VariablesController : Controller
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut("")]
|
[HttpPut]
|
||||||
public async Task<ServerVariableDetailResponse> UpdateSingle(
|
public async Task<ServerVariableDetailResponse> UpdateSingle(
|
||||||
[FromRoute] int serverId,
|
[FromRoute] int serverId,
|
||||||
[FromBody] UpdateServerVariableRequest request
|
[FromBody] UpdateServerVariableRequest request
|
||||||
@@ -123,7 +123,7 @@ public class VariablesController : Controller
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPatch("")]
|
[HttpPatch]
|
||||||
public async Task<ServerVariableDetailResponse[]> Update(
|
public async Task<ServerVariableDetailResponse[]> Update(
|
||||||
[FromRoute] int serverId,
|
[FromRoute] int serverId,
|
||||||
[FromBody] UpdateServerVariableRangeRequest request
|
[FromBody] UpdateServerVariableRangeRequest request
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ public class ShareAuthFilter : IServerAuthorizationFilter
|
|||||||
if (string.IsNullOrEmpty(permissionId) || requiredLevel == ServerPermissionLevel.None)
|
if (string.IsNullOrEmpty(permissionId) || requiredLevel == ServerPermissionLevel.None)
|
||||||
return ServerAuthorizationResult.Success(share);
|
return ServerAuthorizationResult.Success(share);
|
||||||
|
|
||||||
if (
|
var possiblePermShare = share.Content.Permissions.FirstOrDefault(x => x.Identifier == permissionId);
|
||||||
share.Content.Permissions.TryGetValue(permissionId, out var shareLevel) &&
|
|
||||||
shareLevel >= requiredLevel
|
if (possiblePermShare == null)
|
||||||
)
|
return null;
|
||||||
{
|
|
||||||
|
if (possiblePermShare.Level >= requiredLevel)
|
||||||
return ServerAuthorizationResult.Success(share);
|
return ServerAuthorizationResult.Success(share);
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
27
MoonlightServers.ApiServer/Mappers/ShareMapper.cs
Normal file
27
MoonlightServers.ApiServer/Mappers/ShareMapper.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using MoonlightServers.ApiServer.Models;
|
||||||
|
using MoonlightServers.Shared.Enums;
|
||||||
|
using Riok.Mapperly.Abstractions;
|
||||||
|
|
||||||
|
namespace MoonlightServers.ApiServer.Mappers;
|
||||||
|
|
||||||
|
[Mapper]
|
||||||
|
public static partial class ShareMapper
|
||||||
|
{
|
||||||
|
public static ServerShareContent MapToServerShareContent(Dictionary<string, ServerPermissionLevel> permissionLevels)
|
||||||
|
{
|
||||||
|
return new ServerShareContent()
|
||||||
|
{
|
||||||
|
Permissions = permissionLevels.Select(x => new ServerShareContent.SharePermission()
|
||||||
|
{
|
||||||
|
Identifier = x.Key,
|
||||||
|
Level = x.Value
|
||||||
|
}).ToList()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, ServerPermissionLevel> MapToPermissionLevels(
|
||||||
|
ServerShareContent content)
|
||||||
|
{
|
||||||
|
return content.Permissions.ToDictionary(x => x.Identifier, x => x.Level);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,13 @@ using MoonlightServers.Shared.Enums;
|
|||||||
|
|
||||||
namespace MoonlightServers.ApiServer.Models;
|
namespace MoonlightServers.ApiServer.Models;
|
||||||
|
|
||||||
public class ServerShareContent
|
public record ServerShareContent
|
||||||
{
|
{
|
||||||
public Dictionary<string, ServerPermissionLevel> Permissions { get; set; } = new();
|
public List<SharePermission> Permissions { get; set; } = new();
|
||||||
|
|
||||||
|
public record SharePermission
|
||||||
|
{
|
||||||
|
public string Identifier { get; set; }
|
||||||
|
public ServerPermissionLevel Level { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
using MoonlightServers.Frontend.Interfaces;
|
||||||
|
using MoonlightServers.Frontend.Models;
|
||||||
|
using MoonlightServers.Shared.Constants;
|
||||||
|
using MoonlightServers.Shared.Http.Responses.Client.Servers;
|
||||||
|
|
||||||
|
namespace MoonlightServers.Frontend.Implementations;
|
||||||
|
|
||||||
|
public class DefaultPermissionProvider : IServerPermissionProvider
|
||||||
|
{
|
||||||
|
public Task<ServerPermission[]> GetPermissions(ServerDetailResponse server)
|
||||||
|
{
|
||||||
|
ServerPermission[] permissions = [
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Identifier = ServerPermissionConstants.Console,
|
||||||
|
Description = "Allows access to the console",
|
||||||
|
DisplayName = "Console",
|
||||||
|
Icon = "icon-square-terminal"
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Identifier = ServerPermissionConstants.Files,
|
||||||
|
Description = "Allows access to the files",
|
||||||
|
DisplayName = "Files",
|
||||||
|
Icon = "icon-folder"
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Identifier = ServerPermissionConstants.Power,
|
||||||
|
Description = "Allows actions like turning off the server and starting it",
|
||||||
|
DisplayName = "Power",
|
||||||
|
Icon = "icon-power"
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Identifier = ServerPermissionConstants.Settings,
|
||||||
|
Description = "Gives permissions to perform re-installs or change other general settings",
|
||||||
|
DisplayName = "Settings",
|
||||||
|
Icon = "icon-settings"
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Identifier = ServerPermissionConstants.Shares,
|
||||||
|
Description = "Dangerous! This allows control to the available shares and their access level for a server",
|
||||||
|
DisplayName = "Shares",
|
||||||
|
Icon = "icon-users"
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Identifier = ServerPermissionConstants.Variables,
|
||||||
|
Description = "Allows access to the server software specific settings",
|
||||||
|
DisplayName = "Variables",
|
||||||
|
Icon = "icon-variable"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return Task.FromResult(permissions);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using MoonlightServers.Frontend.Interfaces;
|
using MoonlightServers.Frontend.Interfaces;
|
||||||
using MoonlightServers.Frontend.Models;
|
using MoonlightServers.Frontend.Models;
|
||||||
using MoonlightServers.Frontend.UI.Components.Servers.ServerTabs;
|
using MoonlightServers.Frontend.UI.Components.Servers.ServerTabs;
|
||||||
|
using MoonlightServers.Shared.Constants;
|
||||||
|
using MoonlightServers.Shared.Enums;
|
||||||
using MoonlightServers.Shared.Http.Responses.Client.Servers;
|
using MoonlightServers.Shared.Http.Responses.Client.Servers;
|
||||||
|
|
||||||
namespace MoonlightServers.Frontend.Implementations;
|
namespace MoonlightServers.Frontend.Implementations;
|
||||||
@@ -11,11 +13,11 @@ public class DefaultServerTabProvider : IServerTabProvider
|
|||||||
{
|
{
|
||||||
ServerTab[] tabs =
|
ServerTab[] tabs =
|
||||||
[
|
[
|
||||||
ServerTab.CreateFromComponent<ConsoleTab>("Console", "console", 0, permission => permission.Identifier == "console"),
|
ServerTab.CreateFromComponent<ConsoleTab>("Console", "console", 0, ServerPermissionConstants.Console, ServerPermissionLevel.Read),
|
||||||
ServerTab.CreateFromComponent<FilesTab>("Files", "files", 1, permission => permission.Identifier == "files"),
|
ServerTab.CreateFromComponent<FilesTab>("Files", "files", 1, ServerPermissionConstants.Files, ServerPermissionLevel.Read),
|
||||||
ServerTab.CreateFromComponent<SharesTab>("Shares", "shares", 2, permission => permission.Identifier == "shares"),
|
ServerTab.CreateFromComponent<SharesTab>("Shares", "shares", 2, ServerPermissionConstants.Shares, ServerPermissionLevel.ReadWrite),
|
||||||
ServerTab.CreateFromComponent<VariablesTab>("Variables", "variables", 9, permission => permission.Identifier == "variables"),
|
ServerTab.CreateFromComponent<VariablesTab>("Variables", "variables", 9, ServerPermissionConstants.Variables, ServerPermissionLevel.Read),
|
||||||
ServerTab.CreateFromComponent<SettingsTab>("Settings", "settings", 10, permission => permission.Identifier == "settings"),
|
ServerTab.CreateFromComponent<SettingsTab>("Settings", "settings", 10, ServerPermissionConstants.Settings, ServerPermissionLevel.Read),
|
||||||
];
|
];
|
||||||
|
|
||||||
return Task.FromResult(tabs);
|
return Task.FromResult(tabs);
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using MoonlightServers.Frontend.Models;
|
||||||
|
using MoonlightServers.Shared.Http.Responses.Client.Servers;
|
||||||
|
|
||||||
|
namespace MoonlightServers.Frontend.Interfaces;
|
||||||
|
|
||||||
|
public interface IServerPermissionProvider
|
||||||
|
{
|
||||||
|
public Task<ServerPermission[]> GetPermissions(ServerDetailResponse server);
|
||||||
|
}
|
||||||
9
MoonlightServers.Frontend/Models/ServerPermission.cs
Normal file
9
MoonlightServers.Frontend/Models/ServerPermission.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace MoonlightServers.Frontend.Models;
|
||||||
|
|
||||||
|
public record ServerPermission
|
||||||
|
{
|
||||||
|
public string Identifier { get; set; }
|
||||||
|
public string DisplayName { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public string Icon { get; set; }
|
||||||
|
}
|
||||||
@@ -112,10 +112,10 @@ public class ServerService
|
|||||||
|
|
||||||
#region Variables
|
#region Variables
|
||||||
|
|
||||||
public async Task<ServerVariableDetailResponse[]> GetVariables(int serverId)
|
public async Task<PagedData<ServerVariableDetailResponse>> GetVariables(int serverId, int page, int pageSize)
|
||||||
{
|
{
|
||||||
return await HttpApiClient.GetJson<ServerVariableDetailResponse[]>(
|
return await HttpApiClient.GetJson<PagedData<ServerVariableDetailResponse>>(
|
||||||
$"api/client/servers/{serverId}/variables"
|
$"api/client/servers/{serverId}/variables?page={page}&pageSize={pageSize}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public class PluginStartup : IPluginStartup
|
|||||||
{
|
{
|
||||||
builder.Services.AddSingleton<ISidebarItemProvider, SidebarImplementation>();
|
builder.Services.AddSingleton<ISidebarItemProvider, SidebarImplementation>();
|
||||||
builder.Services.AddSingleton<IServerTabProvider, DefaultServerTabProvider>();
|
builder.Services.AddSingleton<IServerTabProvider, DefaultServerTabProvider>();
|
||||||
|
builder.Services.AddSingleton<IServerPermissionProvider, DefaultPermissionProvider>();
|
||||||
|
|
||||||
builder.Services.AutoAddServices<PluginStartup>();
|
builder.Services.AutoAddServices<PluginStartup>();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
@using MoonCore.Blazor.FlyonUi.Components
|
@using MoonCore.Blazor.FlyonUi.Components
|
||||||
@using MoonlightServers.Shared.Enums
|
@using MoonlightServers.Shared.Enums
|
||||||
@using MoonlightServers.Shared.Http.Requests.Client.Servers.Shares
|
@using MoonlightServers.Shared.Http.Requests.Client.Servers.Shares
|
||||||
@using MoonlightServers.Shared.Models
|
@using MoonlightServers.Shared.Http.Responses.Client.Servers
|
||||||
|
|
||||||
@inherits MoonCore.Blazor.FlyonUi.Modals.Components.BaseModal
|
@inherits MoonCore.Blazor.FlyonUi.Modals.Components.BaseModal
|
||||||
|
|
||||||
@@ -14,48 +14,7 @@
|
|||||||
<label class="block text-sm font-medium leading-6 text-base-content">Username</label>
|
<label class="block text-sm font-medium leading-6 text-base-content">Username</label>
|
||||||
<input @bind="Request.Username" type="text" class="input w-full"/>
|
<input @bind="Request.Username" type="text" class="input w-full"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-y-5 lg:gap-y-3">
|
<PermissionEditor Server="Server" PermissionLevels="Permissions" />
|
||||||
@foreach (var name in Names)
|
|
||||||
{
|
|
||||||
var i = Permissions.TryGetValue(name, out var permission) ? (int)permission : -1;
|
|
||||||
|
|
||||||
<div class="col-span-1 flex flex-col justify-center lg:justify-start text-center lg:text-start">
|
|
||||||
<span>@name</span>
|
|
||||||
<span class="text-base-content/80 text-sm">This is a long description</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-span-1 flex justify-end">
|
|
||||||
<div class="join drop-shadow">
|
|
||||||
@if (i == -1)
|
|
||||||
{
|
|
||||||
<input class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="None" checked="checked"/>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<input @onclick="() => Reset(name)" class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="None"/>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (i == 0)
|
|
||||||
{
|
|
||||||
<input class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="Read" checked="checked"/>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<input @onclick="() => Set(name, ServerPermissionLevel.Read)" class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="Read"/>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (i == 1)
|
|
||||||
{
|
|
||||||
<input class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="Read & Write" checked="checked"/>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<input @onclick="() => Set(name, ServerPermissionLevel.ReadWrite)" class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="Read & Write"/>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</HandleForm>
|
</HandleForm>
|
||||||
|
|
||||||
<div class="mt-8 flex space-x-2">
|
<div class="mt-8 flex space-x-2">
|
||||||
@@ -65,6 +24,7 @@
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
|
[Parameter] public ServerDetailResponse Server { get; set; }
|
||||||
[Parameter] public string Username { get; set; }
|
[Parameter] public string Username { get; set; }
|
||||||
[Parameter] public Func<CreateShareRequest, Task> OnSubmit { get; set; }
|
[Parameter] public Func<CreateShareRequest, Task> OnSubmit { get; set; }
|
||||||
|
|
||||||
@@ -97,22 +57,12 @@
|
|||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Reset(string name)
|
|
||||||
{
|
|
||||||
Permissions.Remove(name);
|
|
||||||
await InvokeAsync(StateHasChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Submit()
|
private async Task Submit()
|
||||||
=> await HandleForm.Submit();
|
=> await HandleForm.Submit();
|
||||||
|
|
||||||
private async Task OnValidSubmit()
|
private async Task OnValidSubmit()
|
||||||
{
|
{
|
||||||
Request.Permissions = Permissions.Select(x => new GrantedServerPermission()
|
Request.Permissions = Permissions;
|
||||||
{
|
|
||||||
Identifier = x.Key,
|
|
||||||
Level = x.Value
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
await OnSubmit.Invoke(Request);
|
await OnSubmit.Invoke(Request);
|
||||||
await Hide();
|
await Hide();
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
@using MoonlightServers.Frontend.Interfaces
|
||||||
|
@using MoonCore.Blazor.FlyonUi.Components
|
||||||
|
@using MoonlightServers.Frontend.Models
|
||||||
|
@using MoonlightServers.Shared.Enums
|
||||||
|
@using MoonlightServers.Shared.Http.Responses.Client.Servers
|
||||||
|
|
||||||
|
@inject IEnumerable<IServerPermissionProvider> PermissionProviders
|
||||||
|
|
||||||
|
<LazyLoader Load="Load">
|
||||||
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-y-3">
|
||||||
|
@foreach (var permission in AvailablePermissions)
|
||||||
|
{
|
||||||
|
var level = PermissionLevels.GetValueOrDefault(permission.Identifier, ServerPermissionLevel.None);
|
||||||
|
|
||||||
|
<div class="col-span-1 flex flex-row items-center justify-start text-base-content">
|
||||||
|
<i class="text-lg @permission.Icon me-4"></i>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<span>@permission.DisplayName</span>
|
||||||
|
<span class="text-base-content/60 text-sm">@permission.Description</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-span-1 flex justify-start lg:justify-end mb-5 lg:mb-0">
|
||||||
|
<div class="join drop-shadow">
|
||||||
|
@if (level == ServerPermissionLevel.None)
|
||||||
|
{
|
||||||
|
<input class="join-item btn btn-soft" type="radio" name="share-@permission.Identifier"
|
||||||
|
aria-label="None"
|
||||||
|
checked="checked"/>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<input @onclick="() => Set(permission.Identifier, ServerPermissionLevel.None)"
|
||||||
|
class="join-item btn btn-soft"
|
||||||
|
type="radio" name="share-@permission.Identifier" aria-label="None"/>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (level == ServerPermissionLevel.Read)
|
||||||
|
{
|
||||||
|
<input class="join-item btn btn-soft" type="radio" name="share-@permission.Identifier"
|
||||||
|
aria-label="Read"
|
||||||
|
checked="checked"/>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<input @onclick="() => Set(permission.Identifier, ServerPermissionLevel.Read)"
|
||||||
|
class="join-item btn btn-soft"
|
||||||
|
type="radio" name="share-@permission.Identifier" aria-label="Read"/>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (level == ServerPermissionLevel.ReadWrite)
|
||||||
|
{
|
||||||
|
<input class="join-item btn btn-soft" type="radio" name="share-@permission.Identifier"
|
||||||
|
aria-label="Read & Write"
|
||||||
|
checked="checked"/>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<input @onclick="() => Set(permission.Identifier, ServerPermissionLevel.ReadWrite)"
|
||||||
|
class="join-item btn btn-soft"
|
||||||
|
type="radio" name="share-@permission.Identifier" aria-label="Read & Write"/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</LazyLoader>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
[Parameter] public ServerDetailResponse Server { get; set; }
|
||||||
|
[Parameter] public Dictionary<string, ServerPermissionLevel> PermissionLevels { get; set; }
|
||||||
|
|
||||||
|
private ServerPermission[] AvailablePermissions;
|
||||||
|
|
||||||
|
private async Task Load(LazyLoader _)
|
||||||
|
{
|
||||||
|
var permissions = new List<ServerPermission>();
|
||||||
|
|
||||||
|
foreach (var provider in PermissionProviders)
|
||||||
|
{
|
||||||
|
permissions.AddRange(
|
||||||
|
await provider.GetPermissions(Server)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
AvailablePermissions = permissions.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Set(string name, ServerPermissionLevel level)
|
||||||
|
{
|
||||||
|
PermissionLevels[name] = level;
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -75,6 +75,7 @@
|
|||||||
await ModalService.Launch<CreateShareModal>(parameters =>
|
await ModalService.Launch<CreateShareModal>(parameters =>
|
||||||
{
|
{
|
||||||
parameters["Username"] = UsernameInput;
|
parameters["Username"] = UsernameInput;
|
||||||
|
parameters["Server"] = Server;
|
||||||
parameters["OnSubmit"] = SubmitCreate;
|
parameters["OnSubmit"] = SubmitCreate;
|
||||||
}, size: "max-w-2xl");
|
}, size: "max-w-2xl");
|
||||||
}
|
}
|
||||||
@@ -92,6 +93,7 @@
|
|||||||
await ModalService.Launch<UpdateShareModal>(parameters =>
|
await ModalService.Launch<UpdateShareModal>(parameters =>
|
||||||
{
|
{
|
||||||
parameters["Share"] = share;
|
parameters["Share"] = share;
|
||||||
|
parameters["Server"] = Server;
|
||||||
parameters["OnSubmit"] = (UpdateShareRequest request) => SubmitUpdate(share.Id, request);
|
parameters["OnSubmit"] = (UpdateShareRequest request) => SubmitUpdate(share.Id, request);
|
||||||
}, size: "max-w-2xl");
|
}, size: "max-w-2xl");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
@using MoonCore.Blazor.FlyonUi.Components
|
@using MoonCore.Blazor.FlyonUi.Components
|
||||||
@using MoonCore.Blazor.FlyonUi.Toasts
|
@using MoonCore.Blazor.FlyonUi.Toasts
|
||||||
|
@using MoonCore.Models
|
||||||
@using MoonlightServers.Frontend.Services
|
@using MoonlightServers.Frontend.Services
|
||||||
@using MoonlightServers.Shared.Http.Responses.Client.Servers.Variables
|
@using MoonlightServers.Shared.Http.Responses.Client.Servers.Variables
|
||||||
|
|
||||||
@@ -8,7 +9,7 @@
|
|||||||
@inject ServerService ServerService
|
@inject ServerService ServerService
|
||||||
@inject ToastService ToastService
|
@inject ToastService ToastService
|
||||||
|
|
||||||
<LazyLoader Load="Load">
|
<LazyLoader @ref="LazyLoader" Load="Load">
|
||||||
<div class="grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
|
<div class="grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
|
||||||
@foreach (var variable in Variables)
|
@foreach (var variable in Variables)
|
||||||
{
|
{
|
||||||
@@ -37,10 +38,13 @@
|
|||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
private ServerVariableDetailResponse[] Variables;
|
private ServerVariableDetailResponse[] Variables;
|
||||||
|
private LazyLoader LazyLoader;
|
||||||
|
|
||||||
private async Task Load(LazyLoader _)
|
private async Task Load(LazyLoader _)
|
||||||
{
|
{
|
||||||
Variables = await ServerService.GetVariables(Server.Id);
|
Variables = await PagedData<ServerVariableDetailResponse>.All(async (page, pageSize)
|
||||||
|
=> await ServerService.GetVariables(Server.Id, page, pageSize)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UpdateVariable(ServerVariableDetailResponse variable, ChangeEventArgs args)
|
private async Task UpdateVariable(ServerVariableDetailResponse variable, ChangeEventArgs args)
|
||||||
@@ -54,8 +58,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Fetch the current data to make sure the user sees the latest data
|
// Fetch the current data to make sure the user sees the latest data
|
||||||
Variables = await ServerService.GetVariables(Server.Id);
|
await LazyLoader.Reload();
|
||||||
await InvokeAsync(StateHasChanged);
|
|
||||||
|
|
||||||
await ToastService.Success("Successfully updated variable");
|
await ToastService.Success("Successfully updated variable");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
@using MoonCore.Blazor.FlyonUi.Components
|
@using MoonCore.Blazor.FlyonUi.Components
|
||||||
@using MoonlightServers.Shared.Enums
|
@using MoonlightServers.Shared.Enums
|
||||||
@using MoonlightServers.Shared.Http.Requests.Client.Servers.Shares
|
@using MoonlightServers.Shared.Http.Requests.Client.Servers.Shares
|
||||||
|
@using MoonlightServers.Shared.Http.Responses.Client.Servers
|
||||||
@using MoonlightServers.Shared.Http.Responses.Client.Servers.Shares
|
@using MoonlightServers.Shared.Http.Responses.Client.Servers.Shares
|
||||||
@using MoonlightServers.Shared.Models
|
@using MoonlightServers.Shared.Models
|
||||||
|
|
||||||
@@ -11,48 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<HandleForm @ref="HandleForm" Model="Request" OnValidSubmit="OnValidSubmit">
|
<HandleForm @ref="HandleForm" Model="Request" OnValidSubmit="OnValidSubmit">
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-y-5 lg:gap-y-3">
|
<PermissionEditor Server="Server" PermissionLevels="Permissions" />
|
||||||
@foreach (var name in Names)
|
|
||||||
{
|
|
||||||
var i = Permissions.TryGetValue(name, out var permission) ? (int)permission : -1;
|
|
||||||
|
|
||||||
<div class="col-span-1 flex flex-col justify-center lg:justify-start text-center lg:text-start">
|
|
||||||
<span>@name</span>
|
|
||||||
<span class="text-base-content/80 text-sm">This is a long description</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-span-1 flex justify-end">
|
|
||||||
<div class="join drop-shadow">
|
|
||||||
@if (i == -1)
|
|
||||||
{
|
|
||||||
<input class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="None" checked="checked"/>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<input @onclick="() => Reset(name)" class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="None"/>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (i == 0)
|
|
||||||
{
|
|
||||||
<input class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="Read" checked="checked"/>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<input @onclick="() => Set(name, ServerPermissionLevel.Read)" class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="Read"/>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (i == 1)
|
|
||||||
{
|
|
||||||
<input class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="Read & Write" checked="checked"/>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<input @onclick="() => Set(name, ServerPermissionLevel.ReadWrite)" class="join-item btn btn-soft" type="radio" name="share-@name" aria-label="Read & Write"/>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</HandleForm>
|
</HandleForm>
|
||||||
|
|
||||||
<div class="mt-8 flex space-x-2">
|
<div class="mt-8 flex space-x-2">
|
||||||
@@ -62,6 +22,7 @@
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
|
[Parameter] public ServerDetailResponse Server { get; set; }
|
||||||
[Parameter] public ServerShareResponse Share { get; set; }
|
[Parameter] public ServerShareResponse Share { get; set; }
|
||||||
[Parameter] public Func<UpdateShareRequest, Task> OnSubmit { get; set; }
|
[Parameter] public Func<UpdateShareRequest, Task> OnSubmit { get; set; }
|
||||||
|
|
||||||
@@ -84,7 +45,7 @@
|
|||||||
{
|
{
|
||||||
Request = new();
|
Request = new();
|
||||||
|
|
||||||
Permissions = Share.Permissions.ToDictionary(x => x.Identifier, x => x.Level);
|
Permissions = Share.Permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Set(string name, ServerPermissionLevel level)
|
private async Task Set(string name, ServerPermissionLevel level)
|
||||||
@@ -93,22 +54,12 @@
|
|||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Reset(string name)
|
|
||||||
{
|
|
||||||
Permissions.Remove(name);
|
|
||||||
await InvokeAsync(StateHasChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Submit()
|
private async Task Submit()
|
||||||
=> await HandleForm.Submit();
|
=> await HandleForm.Submit();
|
||||||
|
|
||||||
private async Task OnValidSubmit()
|
private async Task OnValidSubmit()
|
||||||
{
|
{
|
||||||
Request.Permissions = Permissions.Select(x => new GrantedServerPermission()
|
Request.Permissions = Permissions;
|
||||||
{
|
|
||||||
Identifier = x.Key,
|
|
||||||
Level = x.Value
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
await OnSubmit.Invoke(Request);
|
await OnSubmit.Invoke(Request);
|
||||||
await Hide();
|
await Hide();
|
||||||
|
|||||||
@@ -223,12 +223,12 @@
|
|||||||
if (string.IsNullOrEmpty(tab.PermissionId) || tab.PermissionLevel == ServerPermissionLevel.None)
|
if (string.IsNullOrEmpty(tab.PermissionId) || tab.PermissionLevel == ServerPermissionLevel.None)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If permission is required but not set, we dont have access to it
|
// If permission is required but not set, we don't have access to it
|
||||||
if (!Server.Share.Permissions.TryGetValue(tab.PermissionId, out var level))
|
if (!Server.Share.Permissions.TryGetValue(tab.PermissionId, out var level))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// True if the acquired level is higher or equal than the required permission level for the tba
|
// False if the acquired level is higher or equal than the required permission level for the tab so it won't get removed
|
||||||
return level >= tab.PermissionLevel;
|
return level < tab.PermissionLevel;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user