Merge remote-tracking branch 'oqtane/dev' into dev
This commit is contained in:
commit
b9e352cbcb
@ -9,189 +9,194 @@
|
||||
@inject IStringLocalizer<Edit> Localizer
|
||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||
|
||||
<TabStrip>
|
||||
<TabPanel Name="Definition" ResourceKey="Definition">
|
||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="name" HelpText="The name of the module" ResourceKey="Name">Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="name" class="form-control" @bind="@_name" maxlength="200" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="description" HelpText="The description of the module" ResourceKey="Description">Description: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="2" maxlength="2000" required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="categories" HelpText="Comma delimited list of module categories" ResourceKey="Categories">Categories: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="categories" class="form-control" @bind="@_categories" maxlength="200" required />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<Section Name="Information" ResourceKey="Information">
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="moduledefinitionname" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="moduledefinitionname" class="form-control" @bind="@_moduledefinitionname" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="version" HelpText="The version of the module" ResourceKey="Version">Version: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="version" class="form-control" @bind="@_version" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="packagename" HelpText="The unique name of the package from which this module was installed" ResourceKey="PackageName">Package Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
||||
@if (_initialized)
|
||||
{
|
||||
<TabStrip>
|
||||
<TabPanel Name="Definition" ResourceKey="Definition">
|
||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="name" HelpText="The name of the module" ResourceKey="Name">Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="name" class="form-control" @bind="@_name" maxlength="200" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="description" HelpText="The description of the module" ResourceKey="Description">Description: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="2" maxlength="2000" required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="categories" HelpText="Comma delimited list of module categories" ResourceKey="Categories">Categories: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="categories" class="form-control" @bind="@_categories" maxlength="200" required />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<Section Name="Information" ResourceKey="Information">
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="moduledefinitionname" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="moduledefinitionname" class="form-control" @bind="@_moduledefinitionname" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="version" HelpText="The version of the module" ResourceKey="Version">Version: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="version" class="form-control" @bind="@_version" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="packagename" HelpText="The unique name of the package from which this module was installed" ResourceKey="PackageName">Package Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="owner" HelpText="The owner or creator of the module" ResourceKey="Owner">Owner: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="owner" class="form-control" @bind="@_owner" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="url" HelpText="The reference url of the module" ResourceKey="ReferenceUrl">Reference Url: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="url" class="form-control" @bind="@_url" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="contact" HelpText="The contact for the module" ResourceKey="Contact">Contact: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="contact" class="form-control" @bind="@_contact" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="license" HelpText="The module license terms" ResourceKey="License">License: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="runtimes" HelpText="The Blazor runtimes which this module supports" ResourceKey="Runtimes">Runtimes: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="runtimes" class="form-control" @bind="@_runtimes" disabled />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
<br />
|
||||
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||
</TabPanel>
|
||||
<TabPanel Name="Permissions" ResourceKey="Permissions">
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="owner" HelpText="The owner or creator of the module" ResourceKey="Owner">Owner: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="owner" class="form-control" @bind="@_owner" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="url" HelpText="The reference url of the module" ResourceKey="ReferenceUrl">Reference Url: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="url" class="form-control" @bind="@_url" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="contact" HelpText="The contact for the module" ResourceKey="Contact">Contact: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="contact" class="form-control" @bind="@_contact" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="license" HelpText="The module license terms" ResourceKey="License">License: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="runtimes" HelpText="The Blazor runtimes which this module supports" ResourceKey="Runtimes">Runtimes: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="runtimes" class="form-control" @bind="@_runtimes" disabled />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
<br />
|
||||
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||
</TabPanel>
|
||||
<TabPanel Name="Permissions" ResourceKey="Permissions">
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<PermissionGrid EntityName="@EntityNames.ModuleDefinition" PermissionNames="@PermissionNames.Utilize" PermissionList="@_permissions" @ref="_permissionGrid" />
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||
</TabPanel>
|
||||
<TabPanel Name="Translations" ResourceKey="Translations">
|
||||
@if (_languages != null && _languages.Count > 0)
|
||||
{
|
||||
<Pager Items="@_languages">
|
||||
<Header>
|
||||
<PermissionGrid EntityName="@EntityNames.ModuleDefinition" PermissionNames="@PermissionNames.Utilize" PermissionList="@_permissions" @ref="_permissionGrid" />
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||
</TabPanel>
|
||||
<TabPanel Name="Translations" ResourceKey="Translations">
|
||||
@if (_languages != null && _languages.Count > 0)
|
||||
{
|
||||
<Pager Items="@_languages">
|
||||
<Header>
|
||||
<th>@SharedLocalizer["Name"]</th>
|
||||
<th>@Localizer["Code"]</th>
|
||||
<th style="width: 1px;">@Localizer["Version"]</th>
|
||||
<th style="width: 1px;"> </th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td>@context.Name</td>
|
||||
<td>@context.Code</td>
|
||||
<td>@((string.IsNullOrEmpty(context.Version)) ? "---" : context.Version)</td>
|
||||
<td>
|
||||
@switch (TranslationAvailable(_packagename + "." + context.Code, context.Version))
|
||||
{
|
||||
case "install":
|
||||
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(_packagename + "." + context.Code))>@SharedLocalizer["Download"]</button>
|
||||
break;
|
||||
case "upgrade":
|
||||
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(_packagename + "." + context.Code))>@SharedLocalizer["Upgrade"]</button>
|
||||
break;
|
||||
}
|
||||
</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
@if (_install)
|
||||
{
|
||||
<button type="button" class="btn btn-success" @onclick="InstallTranslations">@SharedLocalizer["Install"]</button>
|
||||
</Header>
|
||||
<Row>
|
||||
<td>@context.Name</td>
|
||||
<td>@context.Code</td>
|
||||
<td>@((string.IsNullOrEmpty(context.Version)) ? "---" : context.Version)</td>
|
||||
<td>
|
||||
@switch (TranslationAvailable(_packagename + "." + context.Code, context.Version))
|
||||
{
|
||||
case "install":
|
||||
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(_packagename + "." + context.Code))>@SharedLocalizer["Download"]</button>
|
||||
break;
|
||||
case "upgrade":
|
||||
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(_packagename + "." + context.Code))>@SharedLocalizer["Upgrade"]</button>
|
||||
break;
|
||||
}
|
||||
</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
@if (_install)
|
||||
{
|
||||
<button type="button" class="btn btn-success" @onclick="InstallTranslations">@SharedLocalizer["Install"]</button>
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<br />
|
||||
<div class="mx-auto text-center">
|
||||
@if (string.IsNullOrEmpty(_packagename))
|
||||
{
|
||||
@Localizer["Search.PackageNameMissing"]
|
||||
}
|
||||
else
|
||||
{
|
||||
@Localizer["Search.NoResults"]
|
||||
}
|
||||
</div>
|
||||
<br />
|
||||
}
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
else
|
||||
{
|
||||
<br />
|
||||
<div class="mx-auto text-center">
|
||||
@if (string.IsNullOrEmpty(_packagename))
|
||||
{
|
||||
@Localizer["Search.PackageNameMissing"]
|
||||
}
|
||||
else
|
||||
{
|
||||
@Localizer["Search.NoResults"]
|
||||
}
|
||||
</div>
|
||||
<br />
|
||||
}
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
|
||||
@if (_package != null)
|
||||
{
|
||||
<div class="app-actiondialog">
|
||||
<div class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">@SharedLocalizer["Review License Terms"]</h5>
|
||||
<button type="button" class="btn-close" aria-label="Close" @onclick="HideModal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p style="height: 200px; overflow-y: scroll;">
|
||||
<h4 style="display: inline;"><a href="@_package.ProductUrl" target="_new">@_package.Name</a></h4><br />
|
||||
@SharedLocalizer["Search.By"]: <strong><a href="@_package.OwnerUrl" target="new">@_package.Owner</a></strong><br />
|
||||
@(_package.Description.Length > 400 ? (_package.Description.Substring(0, 400) + "...") : _package.Description)<br />
|
||||
<strong>@(String.Format("{0:n0}", _package.Downloads))</strong> @SharedLocalizer["Search.Downloads"] |
|
||||
@SharedLocalizer["Search.Released"]: <strong>@_package.ReleaseDate.ToString("MMM dd, yyyy")</strong> |
|
||||
@SharedLocalizer["Search.Version"]: <strong>@_package.Version</strong>
|
||||
@((MarkupString)(!string.IsNullOrEmpty(_package.PackageUrl) ? " | " + SharedLocalizer["Search.Source"] + ": <strong>" + new Uri(_package.PackageUrl).Host + "</strong>" : ""))
|
||||
<br /><br />
|
||||
@if (!string.IsNullOrEmpty(_package.License))
|
||||
{
|
||||
@((MarkupString)_package.License.Replace("\n", "<br />"))
|
||||
}
|
||||
else
|
||||
{
|
||||
@SharedLocalizer["License Not Specified"]
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-success" @onclick="DownloadPackage">@SharedLocalizer["Accept"]</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="HideModal">@SharedLocalizer["Cancel"]</button>
|
||||
@if (_package != null)
|
||||
{
|
||||
<div class="app-actiondialog">
|
||||
<div class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">@SharedLocalizer["Review License Terms"]</h5>
|
||||
<button type="button" class="btn-close" aria-label="Close" @onclick="HideModal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p style="height: 200px; overflow-y: scroll;">
|
||||
<h4 style="display: inline;"><a href="@_package.ProductUrl" target="_new">@_package.Name</a></h4><br />
|
||||
@SharedLocalizer["Search.By"]: <strong><a href="@_package.OwnerUrl" target="new">@_package.Owner</a></strong><br />
|
||||
@(_package.Description.Length > 400 ? (_package.Description.Substring(0, 400) + "...") : _package.Description)<br />
|
||||
<strong>@(String.Format("{0:n0}", _package.Downloads))</strong> @SharedLocalizer["Search.Downloads"] |
|
||||
@SharedLocalizer["Search.Released"]: <strong>@_package.ReleaseDate.ToString("MMM dd, yyyy")</strong> |
|
||||
@SharedLocalizer["Search.Version"]: <strong>@_package.Version</strong>
|
||||
@((MarkupString)(!string.IsNullOrEmpty(_package.PackageUrl) ? " | " + SharedLocalizer["Search.Source"] + ": <strong>" + new Uri(_package.PackageUrl).Host + "</strong>" : ""))
|
||||
<br /><br />
|
||||
@if (!string.IsNullOrEmpty(_package.License))
|
||||
{
|
||||
@((MarkupString)_package.License.Replace("\n", "<br />"))
|
||||
}
|
||||
else
|
||||
{
|
||||
@SharedLocalizer["License Not Specified"]
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-success" @onclick="DownloadPackage">@SharedLocalizer["Accept"]</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="HideModal">@SharedLocalizer["Cancel"]</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
private bool _initialized = false;
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
private int _moduleDefinitionId;
|
||||
@ -262,6 +267,8 @@
|
||||
}
|
||||
_languages = _languages.OrderBy(item => item.Name).ToList();
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -294,6 +294,12 @@ else
|
||||
<input id="roleclaimtype" class="form-control" @bind="@_roleclaimtype" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="profileclaimtypes" HelpText="A comma delimited list of user profile claims provided by the provider, as well as mappings to your user profile definition. For example if the provider includes a 'given_name' claim and you have a 'FirstName' user profile definition you should specify 'given_name:FirstName'." ResourceKey="ProfileClaimTypes">User Profile Claims:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="profileclaimtypes" class="form-control" @bind="@_profileclaimtypes" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="domainfilter" HelpText="Provide any email domain filter criteria (separated by commas). Domains to exclude should be prefixed with an exclamation point (!). For example 'microsoft.com,!hotmail.com' would include microsoft.com email addresses but not hotmail.com email addresses." ResourceKey="DomainFilter">Domain Filter:</Label>
|
||||
@ -395,6 +401,7 @@ else
|
||||
private string _identifierclaimtype;
|
||||
private string _emailclaimtype;
|
||||
private string _roleclaimtype;
|
||||
private string _profileclaimtypes;
|
||||
private string _domainfilter;
|
||||
private string _createusers;
|
||||
|
||||
@ -449,6 +456,7 @@ else
|
||||
_identifierclaimtype = SettingService.GetSetting(settings, "ExternalLogin:IdentifierClaimType", "sub");
|
||||
_emailclaimtype = SettingService.GetSetting(settings, "ExternalLogin:EmailClaimType", "email");
|
||||
_roleclaimtype = SettingService.GetSetting(settings, "ExternalLogin:RoleClaimType", "");
|
||||
_profileclaimtypes = SettingService.GetSetting(settings, "ExternalLogin:ProfileClaimTypes", "");
|
||||
_domainfilter = SettingService.GetSetting(settings, "ExternalLogin:DomainFilter", "");
|
||||
_createusers = SettingService.GetSetting(settings, "ExternalLogin:CreateUsers", "true");
|
||||
|
||||
@ -568,6 +576,7 @@ else
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:IdentifierClaimType", _identifierclaimtype, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:EmailClaimType", _emailclaimtype, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:RoleClaimType", _roleclaimtype, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:ProfileClaimTypes", _profileclaimtypes, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:DomainFilter", _domainfilter, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:CreateUsers", _createusers, true);
|
||||
|
||||
|
@ -62,7 +62,7 @@
|
||||
public SecurityAccessLevel? Security { get; set; } // optional - can be used to explicitly specify SecurityAccessLevel
|
||||
|
||||
[Parameter]
|
||||
public string Permissions { get; set; } // optional - can be used to specify permissions (deprecated - use PermissionList)
|
||||
public string Permissions { get; set; } // deprecated - use PermissionList instead
|
||||
|
||||
[Parameter]
|
||||
public List<Permission> PermissionList { get; set; } // optional - can be used to specify permissions
|
||||
|
@ -53,7 +53,7 @@
|
||||
public SecurityAccessLevel? Security { get; set; } // optional - can be used to explicitly specify SecurityAccessLevel
|
||||
|
||||
[Parameter]
|
||||
public string Permissions { get; set; } // optional - can be used to specify permissions (deprecated - use PermissionList)
|
||||
public string Permissions { get; set; } // deprecated - use PermissionList instead
|
||||
|
||||
[Parameter]
|
||||
public List<Permission> PermissionList { get; set; } // optional - can be used to specify permissions
|
||||
|
@ -138,7 +138,7 @@
|
||||
|
||||
// initialize permissions
|
||||
_permissions = new List<Permission>();
|
||||
if (PermissionList.Any())
|
||||
if (PermissionList != null && PermissionList.Any())
|
||||
{
|
||||
foreach (var permission in PermissionList)
|
||||
{
|
||||
@ -167,7 +167,7 @@
|
||||
_permissions.Add(new Permission(ModuleState.SiteId, segments[0], segments[1], role, null, true));
|
||||
}
|
||||
// ensure admin access
|
||||
if (!_permissions.Any(item => item.EntityName == segments[0] && item.PermissionName == segments[1] && item.Role.Name == RoleNames.Admin))
|
||||
if (!_permissions.Any(item => item.EntityName == segments[0] && item.PermissionName == segments[1] && item.RoleName == RoleNames.Admin))
|
||||
{
|
||||
_permissions.Add(new Permission(ModuleState.SiteId, segments[0], segments[1], RoleNames.Admin, null, true));
|
||||
}
|
||||
@ -203,7 +203,7 @@
|
||||
bool? isauthorized = null;
|
||||
if (roleName != "")
|
||||
{
|
||||
var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.Role.Name == roleName);
|
||||
var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.RoleName == roleName);
|
||||
if (permission != null)
|
||||
{
|
||||
isauthorized = permission.IsAuthorized;
|
||||
@ -243,7 +243,7 @@
|
||||
{
|
||||
if (roleName != "")
|
||||
{
|
||||
var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.Role.Name == roleName);
|
||||
var permission = _permissions.FirstOrDefault(item => item.EntityName == GetEntityName(permissionName) && item.PermissionName == GetPermissionName(permissionName) && item.RoleName == roleName);
|
||||
if (permission != null)
|
||||
{
|
||||
_permissions.Remove(permission);
|
||||
@ -307,7 +307,7 @@
|
||||
{
|
||||
// remove deny all users, unauthenticated, and registered users
|
||||
var permissions = _permissions.Where(item => !item.IsAuthorized &&
|
||||
(item.Role.Name == RoleNames.Everyone || item.Role.Name == RoleNames.Unauthenticated || item.Role.Name == RoleNames.Registered)).ToList();
|
||||
(item.RoleName == RoleNames.Everyone || item.RoleName == RoleNames.Unauthenticated || item.RoleName == RoleNames.Registered)).ToList();
|
||||
foreach (var permission in permissions)
|
||||
{
|
||||
_permissions.Remove(permission);
|
||||
@ -316,7 +316,7 @@
|
||||
{
|
||||
// remove deny administrators and host users
|
||||
permissions = _permissions.Where(item => !item.IsAuthorized &&
|
||||
(item.Role.Name == RoleNames.Admin || item.Role.Name == RoleNames.Host)).ToList();
|
||||
(item.RoleName == RoleNames.Admin || item.RoleName == RoleNames.Host)).ToList();
|
||||
foreach (var permission in permissions)
|
||||
{
|
||||
_permissions.Remove(permission);
|
||||
@ -325,7 +325,7 @@
|
||||
{
|
||||
// add administrators role if neither host or administrator is assigned
|
||||
if (!_permissions.Any(item => item.EntityName == GetEntityName(permissionname) && item.PermissionName == GetPermissionName(permissionname) &&
|
||||
(item.Role.Name == RoleNames.Admin || item.Role.Name == RoleNames.Host)))
|
||||
(item.RoleName == RoleNames.Admin || item.RoleName == RoleNames.Host)))
|
||||
{
|
||||
_permissions.Add(new Permission(ModuleState.SiteId, GetEntityName(permissionname), GetPermissionName(permissionname), RoleNames.Admin, null, true));
|
||||
}
|
||||
|
@ -387,7 +387,13 @@
|
||||
<data name="RoleClaimType.HelpText" xml:space="preserve">
|
||||
<value>Optionally provide the name of the role claim provided by the identity provider. These roles will be used in addition to any internal user roles assigned within the site.</value>
|
||||
</data>
|
||||
<data name="RoleClaimType.Text" xml:space="preserve">
|
||||
<value>Role Claim Type:</value>
|
||||
<data name="RoleClaimType.Text" xml:space="preserve">
|
||||
<value>Role Claim:</value>
|
||||
</data>
|
||||
<data name="ProfileClaimTypes.HelpText" xml:space="preserve">
|
||||
<value>Optionally provide a comma delimited list of user profile claims provided by the identity provider, as well as mappings to your user profile definition. For example if the identity provider includes a 'given_name' claim and you have a 'FirstName' user profile definition you should specify 'given_name:FirstName'.</value>
|
||||
</data>
|
||||
<data name="ProfileClaimTypes.Text" xml:space="preserve">
|
||||
<value>User Profile Claims:</value>
|
||||
</data>
|
||||
</root>
|
@ -44,7 +44,7 @@ namespace Oqtane.Themes.Controls
|
||||
}
|
||||
actionList.Add(new ActionViewModel { Icon = Icons.Trash, Name = "Delete Module", Action = async (u, m) => await DeleteModule(u, m) });
|
||||
|
||||
if (ModuleState.ModuleDefinition != null && ModuleState.ModuleDefinition.ServerManagerType != "")
|
||||
if (ModuleState.ModuleDefinition != null && ModuleState.ModuleDefinition.IsPortable)
|
||||
{
|
||||
actionList.Add(new ActionViewModel { Name = "" });
|
||||
actionList.Add(new ActionViewModel { Icon = Icons.CloudUpload, Name = "Import Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Import") });
|
||||
@ -137,11 +137,11 @@ namespace Oqtane.Themes.Controls
|
||||
private async Task<string> Publish(string url, PageModule pagemodule)
|
||||
{
|
||||
var permissions = pagemodule.Module.PermissionList;
|
||||
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Everyone))
|
||||
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Everyone))
|
||||
{
|
||||
permissions.Add(new Permission(ModuleState.SiteId, EntityNames.Page, pagemodule.PageId, PermissionNames.View, RoleNames.Everyone, null, true));
|
||||
}
|
||||
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Registered))
|
||||
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Registered))
|
||||
{
|
||||
permissions.Add(new Permission(ModuleState.SiteId, EntityNames.Page, pagemodule.PageId, PermissionNames.View, RoleNames.Registered, null, true));
|
||||
}
|
||||
@ -153,13 +153,13 @@ namespace Oqtane.Themes.Controls
|
||||
private async Task<string> Unpublish(string url, PageModule pagemodule)
|
||||
{
|
||||
var permissions = pagemodule.Module.PermissionList;
|
||||
if (permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Everyone))
|
||||
if (permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Everyone))
|
||||
{
|
||||
permissions.Remove(permissions.First(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Everyone));
|
||||
permissions.Remove(permissions.First(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Everyone));
|
||||
}
|
||||
if (permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Registered))
|
||||
if (permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Registered))
|
||||
{
|
||||
permissions.Remove(permissions.First(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Registered));
|
||||
permissions.Remove(permissions.First(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Registered));
|
||||
}
|
||||
pagemodule.Module.PermissionList = permissions;
|
||||
await ModuleService.UpdateModuleAsync(pagemodule.Module);
|
||||
|
@ -537,11 +537,11 @@
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList))
|
||||
{
|
||||
var permissions = PageState.Page.PermissionList;
|
||||
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Everyone))
|
||||
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Everyone))
|
||||
{
|
||||
permissions.Add(new Permission(PageState.Site.SiteId, EntityNames.Page, PageState.Page.PageId, PermissionNames.View, RoleNames.Everyone, null, true));
|
||||
}
|
||||
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.Role.Name == RoleNames.Registered))
|
||||
if (!permissions.Any(item => item.PermissionName == PermissionNames.View && item.RoleName == RoleNames.Registered))
|
||||
{
|
||||
permissions.Add(new Permission(PageState.Site.SiteId, EntityNames.Page, PageState.Page.PageId, PermissionNames.View, RoleNames.Registered, null, true));
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ namespace Oqtane.Controllers
|
||||
int SiteId;
|
||||
if (int.TryParse(siteid, out SiteId) && SiteId == _alias.SiteId)
|
||||
{
|
||||
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(SiteId).ToList();
|
||||
List<Setting> settings = _settings.GetSettings(EntityNames.Module).ToList();
|
||||
|
||||
foreach (PageModule pagemodule in _pageModules.GetPageModules(SiteId))
|
||||
@ -74,6 +75,8 @@ namespace Oqtane.Controllers
|
||||
module.Order = pagemodule.Order;
|
||||
module.ContainerType = pagemodule.ContainerType;
|
||||
|
||||
module.ModuleDefinition = FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
||||
|
||||
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.PermissionList))
|
||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||
@ -92,6 +95,29 @@ namespace Oqtane.Controllers
|
||||
return modules;
|
||||
}
|
||||
|
||||
private ModuleDefinition FilterModuleDefinition(ModuleDefinition moduleDefinition)
|
||||
{
|
||||
if (moduleDefinition != null)
|
||||
{
|
||||
moduleDefinition.Description = "";
|
||||
moduleDefinition.Categories = "";
|
||||
moduleDefinition.Version = "";
|
||||
moduleDefinition.Owner = "";
|
||||
moduleDefinition.Url = "";
|
||||
moduleDefinition.Contact = "";
|
||||
moduleDefinition.License = "";
|
||||
moduleDefinition.Dependencies = "";
|
||||
moduleDefinition.PermissionNames = "";
|
||||
moduleDefinition.ServerManagerType = "";
|
||||
moduleDefinition.ReleaseVersions = "";
|
||||
moduleDefinition.PackageName = "";
|
||||
moduleDefinition.AssemblyName = "";
|
||||
moduleDefinition.PermissionList = null;
|
||||
moduleDefinition.Template = "";
|
||||
}
|
||||
return moduleDefinition;
|
||||
}
|
||||
|
||||
// GET api/<controller>/5
|
||||
[HttpGet("{id}")]
|
||||
public Module Get(int id)
|
||||
@ -100,7 +126,7 @@ namespace Oqtane.Controllers
|
||||
if (module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User,PermissionNames.View, module.PermissionList))
|
||||
{
|
||||
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
|
||||
module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
||||
module.ModuleDefinition = FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
||||
module.Settings = _settings.GetSettings(EntityNames.Module, id)
|
||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, module.PermissionList))
|
||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||
|
@ -13,6 +13,7 @@ using System.Globalization;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Oqtane.Extensions;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
@ -128,7 +129,8 @@ namespace Oqtane.Controllers
|
||||
module.Order = pagemodule.Order;
|
||||
module.ContainerType = pagemodule.ContainerType;
|
||||
|
||||
module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
||||
module.ModuleDefinition = FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
||||
|
||||
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.PermissionList))
|
||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||
@ -152,6 +154,29 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
private ModuleDefinition FilterModuleDefinition(ModuleDefinition moduleDefinition)
|
||||
{
|
||||
if (moduleDefinition != null)
|
||||
{
|
||||
moduleDefinition.Description = "";
|
||||
moduleDefinition.Categories = "";
|
||||
moduleDefinition.Version = "";
|
||||
moduleDefinition.Owner = "";
|
||||
moduleDefinition.Url = "";
|
||||
moduleDefinition.Contact = "";
|
||||
moduleDefinition.License = "";
|
||||
moduleDefinition.Dependencies = "";
|
||||
moduleDefinition.PermissionNames = "";
|
||||
moduleDefinition.ServerManagerType = "";
|
||||
moduleDefinition.ReleaseVersions = "";
|
||||
moduleDefinition.PackageName = "";
|
||||
moduleDefinition.AssemblyName = "";
|
||||
moduleDefinition.PermissionList = null;
|
||||
moduleDefinition.Template = "";
|
||||
}
|
||||
return moduleDefinition;
|
||||
}
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
|
@ -197,7 +197,7 @@ namespace Oqtane.Extensions
|
||||
}
|
||||
|
||||
// validate user
|
||||
var identity = await ValidateUser(email, id, claims, context.HttpContext);
|
||||
var identity = await ValidateUser(email, id, claims, context.HttpContext, context.Principal);
|
||||
if (identity.Label == ExternalLoginStatus.Success)
|
||||
{
|
||||
identity.AddClaim(new Claim("access_token", context.AccessToken));
|
||||
@ -232,7 +232,7 @@ namespace Oqtane.Extensions
|
||||
var claims = string.Join(", ", context.Principal.Claims.Select(item => item.Type).ToArray());
|
||||
|
||||
// validate user
|
||||
var identity = await ValidateUser(email, id, claims, context.HttpContext);
|
||||
var identity = await ValidateUser(email, id, claims, context.HttpContext, context.Principal);
|
||||
if (identity.Label == ExternalLoginStatus.Success)
|
||||
{
|
||||
// external roles
|
||||
@ -278,7 +278,7 @@ namespace Oqtane.Extensions
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private static async Task<ClaimsIdentity> ValidateUser(string email, string id, string claims, HttpContext httpContext)
|
||||
private static async Task<ClaimsIdentity> ValidateUser(string email, string id, string claims, HttpContext httpContext, ClaimsPrincipal claimsPrincipal)
|
||||
{
|
||||
var _logger = httpContext.RequestServices.GetRequiredService<ILogManager>();
|
||||
ClaimsIdentity identity = new ClaimsIdentity(Constants.AuthenticationScheme);
|
||||
@ -427,6 +427,40 @@ namespace Oqtane.Extensions
|
||||
user.LastLoginOn = DateTime.UtcNow;
|
||||
user.LastIPAddress = httpContext.Connection.RemoteIpAddress.ToString();
|
||||
_users.UpdateUser(user);
|
||||
|
||||
// user profile claims
|
||||
if (!string.IsNullOrEmpty(httpContext.GetSiteSettings().GetValue("ExternalLogin:ProfileClaimTypes", "")))
|
||||
{
|
||||
var _settings = httpContext.RequestServices.GetRequiredService<ISettingRepository>();
|
||||
var _profiles = httpContext.RequestServices.GetRequiredService<IProfileRepository>();
|
||||
var profiles = _profiles.GetProfiles(user.SiteId);
|
||||
foreach (var mapping in httpContext.GetSiteSettings().GetValue("ExternalLogin:ProfileClaimTypes", "").Split(',', StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (mapping.Contains(":"))
|
||||
{
|
||||
var claim = claimsPrincipal.Claims.FirstOrDefault(item => item.Type == mapping.Split(":")[0]);
|
||||
if (claim != null && !string.IsNullOrEmpty(claim.Value))
|
||||
{
|
||||
var profile = profiles.FirstOrDefault(item => item.Name == mapping.Split(":")[1]);
|
||||
if (profile != null)
|
||||
{
|
||||
var setting = _settings.GetSetting(EntityNames.User, user.UserId, profile.Name);
|
||||
if (setting != null)
|
||||
{
|
||||
setting.SettingValue = claim.Value;
|
||||
_settings.UpdateSetting(setting);
|
||||
}
|
||||
else
|
||||
{
|
||||
setting = new Setting { EntityName = EntityNames.User, EntityId = user.UserId, SettingName = profile.Name, SettingValue = claim.Value, IsPrivate = profile.IsPrivate };
|
||||
_settings.AddSetting(setting);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Log(LogLevel.Information, "ExternalLogin", Enums.LogFunction.Security, "External User Login Successful For {Username} Using Provider {Provider}", user.Username, providerName);
|
||||
}
|
||||
}
|
||||
|
@ -4,14 +4,10 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Security.Policy;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Oqtane.Extensions;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Modules;
|
||||
using Oqtane.Modules.Admin.Roles;
|
||||
using Oqtane.Modules.Admin.Users;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
@ -85,7 +81,7 @@ namespace Oqtane.Repository
|
||||
if (permissions.Count == 0)
|
||||
{
|
||||
// no module definition permissions exist for this site
|
||||
moduledefinition.PermissionList = ClonePermissions(moduledefinition.PermissionList);
|
||||
moduledefinition.PermissionList = ClonePermissions(siteId, moduledefinition.PermissionList);
|
||||
_permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId, moduledefinition.PermissionList);
|
||||
}
|
||||
else
|
||||
@ -97,7 +93,7 @@ namespace Oqtane.Repository
|
||||
else
|
||||
{
|
||||
// permissions for module definition do not exist for this site
|
||||
moduledefinition.PermissionList = ClonePermissions(moduledefinition.PermissionList);
|
||||
moduledefinition.PermissionList = ClonePermissions(siteId, moduledefinition.PermissionList);
|
||||
_permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId, moduledefinition.PermissionList);
|
||||
}
|
||||
}
|
||||
@ -239,6 +235,16 @@ namespace Oqtane.Repository
|
||||
moduledefinition.ControlTypeTemplate = modulecontroltype.Namespace + "." + Constants.ActionToken + ", " + modulecontroltype.Assembly.GetName().Name;
|
||||
moduledefinition.AssemblyName = assembly.GetName().Name;
|
||||
|
||||
moduledefinition.IsPortable = false;
|
||||
if (!string.IsNullOrEmpty(moduledefinition.ServerManagerType))
|
||||
{
|
||||
Type servertype = Type.GetType(moduledefinition.ServerManagerType);
|
||||
if (servertype != null && servertype.GetInterface("IPortable") != null)
|
||||
{
|
||||
moduledefinition.IsPortable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(moduledefinition.Categories))
|
||||
{
|
||||
moduledefinition.Categories = "Common";
|
||||
@ -283,17 +289,18 @@ namespace Oqtane.Repository
|
||||
return moduledefinitions;
|
||||
}
|
||||
|
||||
private List<Permission> ClonePermissions(List<Permission> permissionList)
|
||||
private List<Permission> ClonePermissions(int siteId, List<Permission> permissionList)
|
||||
{
|
||||
var permissions = new List<Permission>();
|
||||
foreach (var p in permissionList)
|
||||
{
|
||||
var permission = new Permission();
|
||||
permission.SiteId = p.SiteId;
|
||||
permission.SiteId = siteId;
|
||||
permission.EntityName = p.EntityName;
|
||||
permission.EntityId = p.EntityId;
|
||||
permission.PermissionName = p.PermissionName;
|
||||
permission.RoleId = p.RoleId;
|
||||
permission.RoleName = p.RoleName;
|
||||
permission.UserId = p.UserId;
|
||||
permission.IsAuthorized = p.IsAuthorized;
|
||||
permissions.Add(permission);
|
||||
|
@ -30,10 +30,17 @@ namespace Oqtane.Repository
|
||||
{
|
||||
return _cache.GetOrCreate($"permissions:{alias.TenantId}:{siteId}:{entityName}", entry =>
|
||||
{
|
||||
var roles = _roles.GetRoles(siteId, true).ToList();
|
||||
var permissions = _db.Permission.Where(item => item.SiteId == siteId).Where(item => item.EntityName == entityName).ToList();
|
||||
foreach (var permission in permissions)
|
||||
{
|
||||
if (permission.RoleId != null)
|
||||
{
|
||||
permission.RoleName = roles.Find(item => item.RoleId == permission.RoleId).Name;
|
||||
}
|
||||
}
|
||||
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||
return _db.Permission.Where(item => item.SiteId == siteId)
|
||||
.Where(item => item.EntityName == entityName)
|
||||
.Include(item => item.Role).ToList(); // eager load roles
|
||||
return permissions;
|
||||
});
|
||||
}
|
||||
return null;
|
||||
@ -84,15 +91,14 @@ namespace Oqtane.Repository
|
||||
permission.SiteId = siteId;
|
||||
permission.EntityName = (string.IsNullOrEmpty(permission.EntityName)) ? entityName : permission.EntityName;
|
||||
permission.EntityId = (permission.EntityName == entityName) ? entityId : -1;
|
||||
if (permission.RoleId == null && permission.Role != null && !string.IsNullOrEmpty(permission.Role.Name))
|
||||
if (permission.UserId == null && permission.RoleId == null && !string.IsNullOrEmpty(permission.RoleName))
|
||||
{
|
||||
var role = roles.FirstOrDefault(item => item.Name == permission.Role.Name);
|
||||
var role = roles.FirstOrDefault(item => item.Name == permission.RoleName);
|
||||
if (role != null)
|
||||
{
|
||||
permission.RoleId = role.RoleId;
|
||||
}
|
||||
}
|
||||
permission.Role = null;
|
||||
}
|
||||
// add or update permissions
|
||||
bool modified = false;
|
||||
@ -112,7 +118,6 @@ namespace Oqtane.Repository
|
||||
if (current.IsAuthorized != permission.IsAuthorized)
|
||||
{
|
||||
current.IsAuthorized = permission.IsAuthorized;
|
||||
current.Role = null; // remove linked reference to Role which can cause errors in EF Core change tracking
|
||||
_db.Entry(current).State = EntityState.Modified;
|
||||
modified = true;
|
||||
}
|
||||
@ -129,7 +134,6 @@ namespace Oqtane.Repository
|
||||
if (!permissions.Any(item => item.EntityName == permission.EntityName && item.PermissionName == permission.PermissionName
|
||||
&& item.EntityId == permission.EntityId && item.RoleId == permission.RoleId && item.UserId == permission.UserId))
|
||||
{
|
||||
permission.Role = null; // remove linked reference to Role which can cause errors in EF Core change tracking
|
||||
_db.Permission.Remove(permission);
|
||||
modified = true;
|
||||
}
|
||||
|
@ -52,14 +52,9 @@ namespace Oqtane.Security
|
||||
return IsAuthorized(principal, permissionName, _permissions.GetPermissions(siteId, entityName, entityId, permissionName).ToList());
|
||||
}
|
||||
|
||||
public bool IsAuthorized(ClaimsPrincipal principal, string permissionName, List<Permission> permissions)
|
||||
public bool IsAuthorized(ClaimsPrincipal principal, string permissionName, List<Permission> permissionList)
|
||||
{
|
||||
return UserSecurity.IsAuthorized(GetUser(principal), permissionName, permissions);
|
||||
}
|
||||
|
||||
public bool IsAuthorized(ClaimsPrincipal principal, string permissionName, string permissions)
|
||||
{
|
||||
return UserSecurity.IsAuthorized(GetUser(principal), permissionName, JsonSerializer.Deserialize<List<Permission>>(permissions));
|
||||
return UserSecurity.IsAuthorized(GetUser(principal), permissionName, permissionList);
|
||||
}
|
||||
|
||||
public User GetUser(ClaimsPrincipal principal)
|
||||
@ -106,5 +101,11 @@ namespace Oqtane.Security
|
||||
{
|
||||
return IsAuthorized(principal, permissionName, _permissions.GetPermissions(_accessor.HttpContext.GetAlias().SiteId, entityName, entityId, permissionName).ToList());
|
||||
}
|
||||
|
||||
[Obsolete("IsAuthorized(ClaimsPrincipal principal, string permissionName, string permissions) is deprecated. Use IsAuthorized(ClaimsPrincipal principal, string permissionName, List<Permission> permissionList) instead", false)]
|
||||
public bool IsAuthorized(ClaimsPrincipal principal, string permissionName, string permissions)
|
||||
{
|
||||
return UserSecurity.IsAuthorized(GetUser(principal), permissionName, JsonSerializer.Deserialize<List<Permission>>(permissions));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Oqtane.Models
|
||||
{
|
||||
@ -85,18 +86,19 @@ namespace Oqtane.Models
|
||||
[NotMapped]
|
||||
public bool HasChildren { get; set; }
|
||||
|
||||
#region Deprecated Properties
|
||||
|
||||
[Obsolete("The Permissions property is deprecated. Use PermissionList instead", false)]
|
||||
[NotMapped]
|
||||
[JsonIgnore] // exclude from API payload
|
||||
public string Permissions
|
||||
{
|
||||
get
|
||||
{
|
||||
return JsonSerializer.Serialize(PermissionList);
|
||||
}
|
||||
set
|
||||
{
|
||||
PermissionList = JsonSerializer.Deserialize<List<Permission>>(Permissions);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Oqtane.Models
|
||||
{
|
||||
@ -109,18 +110,19 @@ namespace Oqtane.Models
|
||||
|
||||
#endregion
|
||||
|
||||
#region Deprecated Properties
|
||||
|
||||
[Obsolete("The Permissions property is deprecated. Use PermissionList instead", false)]
|
||||
[NotMapped]
|
||||
[JsonIgnore] // exclude from API payload
|
||||
public string Permissions
|
||||
{
|
||||
get
|
||||
{
|
||||
return JsonSerializer.Serialize(PermissionList);
|
||||
}
|
||||
set
|
||||
{
|
||||
PermissionList = JsonSerializer.Deserialize<List<Permission>>(Permissions);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Oqtane.Documentation;
|
||||
|
||||
namespace Oqtane.Models
|
||||
@ -68,55 +69,75 @@ namespace Oqtane.Models
|
||||
// additional IModule properties
|
||||
[NotMapped]
|
||||
public string Owner { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string Url { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string Contact { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string License { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string Runtimes { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string Dependencies { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string PermissionNames { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string ServerManagerType { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string ControlTypeRoutes { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string ReleaseVersions { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string DefaultAction { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string SettingsType { get; set; } // added in 2.0.2
|
||||
|
||||
[NotMapped]
|
||||
public string PackageName { get; set; } // added in 2.1.0
|
||||
|
||||
// internal properties
|
||||
[NotMapped]
|
||||
public int SiteId { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string ControlTypeTemplate { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string AssemblyName { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public List<Permission> PermissionList { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string Template { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public bool IsPortable { get; set; }
|
||||
|
||||
#region Deprecated Properties
|
||||
|
||||
[Obsolete("The Permissions property is deprecated. Use PermissionList instead", false)]
|
||||
[NotMapped]
|
||||
[JsonIgnore] // exclude from API payload
|
||||
public string Permissions
|
||||
{
|
||||
get
|
||||
{
|
||||
return JsonSerializer.Serialize(PermissionList);
|
||||
}
|
||||
set
|
||||
{
|
||||
PermissionList = JsonSerializer.Deserialize<List<Permission>>(Permissions);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Oqtane.Models
|
||||
{
|
||||
@ -115,26 +116,24 @@ namespace Oqtane.Models
|
||||
|
||||
#region Deprecated Properties
|
||||
|
||||
[Obsolete("This property is deprecated", false)]
|
||||
[Obsolete("The EditMode property is deprecated", false)]
|
||||
[NotMapped]
|
||||
public bool EditMode { get; set; }
|
||||
|
||||
[Obsolete("This property is deprecated", false)]
|
||||
[Obsolete("The LayoutType property is deprecated", false)]
|
||||
[NotMapped]
|
||||
public string LayoutType { get; set; }
|
||||
|
||||
[Obsolete("The Permissions property is deprecated. Use PermissionList instead", false)]
|
||||
[NotMapped]
|
||||
[JsonIgnore] // exclude from API payload
|
||||
public string Permissions {
|
||||
get
|
||||
{
|
||||
return JsonSerializer.Serialize(PermissionList);
|
||||
}
|
||||
set
|
||||
{
|
||||
PermissionList = JsonSerializer.Deserialize<List<Permission>>(Permissions);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
using System;
|
||||
|
||||
namespace Oqtane.Models
|
||||
{
|
||||
/// <summary>
|
||||
@ -17,47 +21,41 @@ namespace Oqtane.Models
|
||||
public int SiteId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the Entity these permissions apply to.
|
||||
/// Name of the Entity these permissions apply to (ie. Module )
|
||||
/// </summary>
|
||||
public string EntityName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID of the Entity these permissions apply to.
|
||||
/// ID of the Entity these permissions apply to (ie. a ModuleId). A value of -1 indicates the permission applies to all EntityNames regardless of ID (ie. API permissions)
|
||||
/// </summary>
|
||||
public int EntityId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// What this permission is called.
|
||||
/// TODO: todoc - must clarify what exactly this means, I assume any module can give it's own names for Permissions
|
||||
/// Name of the permission (ie. View)
|
||||
/// </summary>
|
||||
public string PermissionName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Role"/> this permission applies to. So if all users in the Role _Customers_ have this permission, then it would reference that Role.
|
||||
/// If null, then the permission doesn't target a role but probably a <see cref="User"/> (see <see cref="UserId"/>).
|
||||
/// <see cref="Role"/> this permission applies to. If null then this is a <see cref="User"/> permission.
|
||||
/// </summary>
|
||||
public int? RoleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The role name associated to the RoleId.
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public string RoleName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="User"/> this permission applies to.
|
||||
/// If null, then the permission doesn't target a User but probably a <see cref="Role"/> (see <see cref="RoleId"/>).
|
||||
/// <see cref="User"/> this permission applies to. If null then this is a <see cref="Role"/> permission.
|
||||
/// </summary>
|
||||
public int? UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines if Authorization is sufficient to receive this permission.
|
||||
/// The type of permission (ie. grant = true, deny = false)
|
||||
/// </summary>
|
||||
public bool IsAuthorized { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the <see cref="Role"/> based on the <see cref="RoleId"/> - can be nullable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It's not certain if this will always be populated. TODO: todoc/verify
|
||||
/// </remarks>
|
||||
public Role Role { get; set; }
|
||||
|
||||
public Permission()
|
||||
{
|
||||
}
|
||||
@ -90,17 +88,22 @@ namespace Oqtane.Models
|
||||
PermissionName = permissionName;
|
||||
if (!string.IsNullOrEmpty(roleName))
|
||||
{
|
||||
Role = new Role { Name = roleName };
|
||||
RoleId = null;
|
||||
RoleName = roleName;
|
||||
UserId = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Role = null;
|
||||
RoleId = null;
|
||||
RoleName = null;
|
||||
UserId = userId;
|
||||
}
|
||||
IsAuthorized = isAuthorized;
|
||||
}
|
||||
|
||||
[Obsolete("The Role property is deprecated", false)]
|
||||
[NotMapped]
|
||||
[JsonIgnore] // exclude from API payload
|
||||
public Role Role { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -33,10 +33,6 @@ namespace Oqtane.Models
|
||||
{
|
||||
return JsonSerializer.Serialize(PermissionList);
|
||||
}
|
||||
set
|
||||
{
|
||||
PermissionList = JsonSerializer.Deserialize<List<Permission>>(PagePermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,10 +51,6 @@ namespace Oqtane.Models
|
||||
{
|
||||
return JsonSerializer.Serialize(PermissionList);
|
||||
}
|
||||
set
|
||||
{
|
||||
PermissionList = JsonSerializer.Deserialize<List<Permission>>(ModulePermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,56 +20,51 @@ namespace Oqtane.Security
|
||||
return IsAuthorized(user, permissions);
|
||||
}
|
||||
|
||||
public static bool IsAuthorized(User user, string permissionName, List<Permission> permissions)
|
||||
public static bool IsAuthorized(User user, string permissionName, List<Permission> permissionList)
|
||||
{
|
||||
return IsAuthorized(user, permissions.Where(item => item.PermissionName == permissionName).ToList());
|
||||
return IsAuthorized(user, permissionList.Where(item => item.PermissionName == permissionName).ToList());
|
||||
}
|
||||
|
||||
public static bool IsAuthorized(User user, string permissionName, string permissions)
|
||||
{
|
||||
return IsAuthorized(user, JsonSerializer.Deserialize<List<Permission>>(permissions).Where(item => item.PermissionName == permissionName).ToList());
|
||||
}
|
||||
|
||||
public static bool IsAuthorized(User user, List<Permission> permissions)
|
||||
public static bool IsAuthorized(User user, List<Permission> permissionList)
|
||||
{
|
||||
bool authorized = false;
|
||||
if (permissions != null && permissions.Any())
|
||||
if (permissionList != null && permissionList.Any())
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
authorized = IsAuthorized(-1, "", permissions); // user is not authenticated but may have access to resource
|
||||
authorized = IsAuthorized(-1, "", permissionList); // user is not authenticated but may have access to resource
|
||||
}
|
||||
else
|
||||
{
|
||||
authorized = IsAuthorized(user.UserId, user.Roles, permissions);
|
||||
authorized = IsAuthorized(user.UserId, user.Roles, permissionList);
|
||||
}
|
||||
|
||||
}
|
||||
return authorized;
|
||||
}
|
||||
|
||||
private static bool IsAuthorized(int userId, string roles, List<Permission> permissions)
|
||||
private static bool IsAuthorized(int userId, string roles, List<Permission> permissionList)
|
||||
{
|
||||
bool isAuthorized = false;
|
||||
|
||||
if (permissions != null && permissions.Any())
|
||||
if (permissionList != null && permissionList.Any())
|
||||
{
|
||||
// check if denied first
|
||||
isAuthorized = !permissions.Where(item => !item.IsAuthorized && (
|
||||
(item.Role != null && (
|
||||
(item.Role.Name == RoleNames.Everyone) ||
|
||||
(item.Role.Name == RoleNames.Unauthenticated && userId == -1) ||
|
||||
roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(item.Role.Name))) ||
|
||||
isAuthorized = !permissionList.Where(item => !item.IsAuthorized && (
|
||||
(item.UserId == null && (
|
||||
(item.RoleName == RoleNames.Everyone) ||
|
||||
(item.RoleName == RoleNames.Unauthenticated && userId == -1) ||
|
||||
roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(item.RoleName))) ||
|
||||
(item.UserId != null && item.UserId.Value == userId))).Any();
|
||||
|
||||
if (isAuthorized)
|
||||
{
|
||||
// then check if authorized
|
||||
isAuthorized = permissions.Where(item => item.IsAuthorized && (
|
||||
(item.Role != null && (
|
||||
(item.Role.Name == RoleNames.Everyone) ||
|
||||
(item.Role.Name == RoleNames.Unauthenticated && userId == -1) ||
|
||||
roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(item.Role.Name))) ||
|
||||
isAuthorized = permissionList.Where(item => item.IsAuthorized && (
|
||||
(item.UserId == null && (
|
||||
(item.RoleName == RoleNames.Everyone) ||
|
||||
(item.RoleName == RoleNames.Unauthenticated && userId == -1) ||
|
||||
roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(item.RoleName))) ||
|
||||
(item.UserId != null && item.UserId.Value == userId))).Any();
|
||||
}
|
||||
}
|
||||
@ -79,7 +74,7 @@ namespace Oqtane.Security
|
||||
|
||||
public static bool ContainsRole(List<Permission> permissions, string permissionName, string roleName)
|
||||
{
|
||||
return permissions.Any(item => item.PermissionName == permissionName && item.Role.Name == roleName);
|
||||
return permissions.Any(item => item.PermissionName == permissionName && item.RoleName == roleName);
|
||||
}
|
||||
|
||||
public static bool ContainsUser(List<Permission> permissions, string permissionName, int userId)
|
||||
@ -123,5 +118,11 @@ namespace Oqtane.Security
|
||||
}
|
||||
return identity;
|
||||
}
|
||||
|
||||
[Obsolete("IsAuthorized(User user, string permissionName, string permissions) is deprecated. Use IsAuthorized(User user, string permissionName, List<Permission> permissionList) instead", false)]
|
||||
public static bool IsAuthorized(User user, string permissionName, string permissions)
|
||||
{
|
||||
return IsAuthorized(user, JsonSerializer.Deserialize<List<Permission>>(permissions).Where(item => item.PermissionName == permissionName).ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user