add support for API permissions at the UI layer - including ability to delegate user, role, profile management

This commit is contained in:
Shaun Walker
2023-01-09 11:38:25 -05:00
parent 1616f94b86
commit e136972cd7
50 changed files with 628 additions and 799 deletions

View File

@ -22,22 +22,15 @@ namespace Oqtane.Security
if (policy == null)
{
// policy names must be in the form of "EntityName:PermissionName:Roles" ie. "Module:Edit:Administrators" (roles are comma delimited)
// policy names must be in the form of "EntityName:PermissionName:Roles"
if (policyName.Contains(':'))
{
var policySegments = policyName.Split(':');
if (policySegments.Length >= 3)
var segments = policyName.Split(':');
if (segments.Length == 3)
{
// check for optional RequireEntityId segment
var requireEntityId = false;
if (policySegments.Length == 4 && policySegments[3] == Constants.RequireEntityId)
{
requireEntityId = true;
}
// create policy
var builder = new AuthorizationPolicyBuilder();
builder.AddRequirements(new PermissionRequirement(policySegments[0], policySegments[1], policySegments[2], requireEntityId));
builder.AddRequirements(new PermissionRequirement(segments[0], segments[1], segments[2]));
policy = builder.Build();
// add policy to the AuthorizationOptions
@ -59,8 +52,8 @@ namespace Oqtane.Security
private string GetPolicyName(string policyName)
{
// backward compatibility for legacy static policy names
if (policyName == PolicyNames.ViewModule) policyName = $"{EntityNames.Module}:{PermissionNames.View}:{RoleNames.Admin}:{Constants.RequireEntityId}";
if (policyName == PolicyNames.EditModule) policyName = $"{EntityNames.Module}:{PermissionNames.Edit}:{RoleNames.Admin}:{Constants.RequireEntityId}";
if (policyName == PolicyNames.ViewModule) policyName = $"{EntityNames.Module}:{PermissionNames.View}:{RoleNames.Admin}";
if (policyName == PolicyNames.EditModule) policyName = $"{EntityNames.Module}:{PermissionNames.Edit}:{RoleNames.Admin}";
return policyName;
}
}

View File

@ -34,28 +34,26 @@ namespace Oqtane.Security
}
int entityId = -1;
if (requirement.RequireEntityId)
// get entityid from querystring based on a parameter format of auth{entityname}id (ie. authmoduleid )
if (ctx.Request.Query.ContainsKey("auth" + requirement.EntityName.ToLower() + "id"))
{
// get entityid from querystring based on a parameter format of auth{entityname}id (ie. authmoduleid )
if (ctx.Request.Query.ContainsKey("auth" + requirement.EntityName.ToLower() + "id"))
if (!int.TryParse(ctx.Request.Query["auth" + requirement.EntityName.ToLower() + "id"], out entityId))
{
if (!int.TryParse(ctx.Request.Query["auth" + requirement.EntityName.ToLower() + "id"], out entityId))
entityId = -1;
}
}
// legacy support for deprecated CreateAuthorizationPolicyUrl(string url, int entityId)
if (entityId == -1)
{
if (ctx.Request.Query.ContainsKey("entityid"))
{
if (!int.TryParse(ctx.Request.Query["entityid"], out entityId))
{
entityId = -1;
}
}
// legacy support for deprecated CreateAuthorizationPolicyUrl(string url, int entityId)
if (entityId == -1)
{
if (ctx.Request.Query.ContainsKey("entityid"))
{
if (!int.TryParse(ctx.Request.Query["entityid"], out entityId))
{
entityId = -1;
}
}
}
}
// validate permissions

View File

@ -8,16 +8,13 @@ namespace Oqtane.Security
public string PermissionName { get; }
public string Roles { get; }
public string Roles { get; } // semi-colon delimited
public bool RequireEntityId { get; }
public PermissionRequirement(string entityName, string permissionName, string roles, bool requireEntityId)
public PermissionRequirement(string entityName, string permissionName, string roles)
{
EntityName = entityName;
PermissionName = permissionName;
Roles = roles;
RequireEntityId = requireEntityId;
}
}
}

View File

@ -40,7 +40,7 @@ namespace Oqtane.Security
}
else
{
return UserSecurity.IsAuthorized(GetUser(principal), roles.Replace(",",";"));
return UserSecurity.IsAuthorized(GetUser(principal), roles);
}
}