Skip to content

Commit

Permalink
Merge pull request #944 from solliancenet/aa-agents-rbac-rebased
Browse files Browse the repository at this point in the history
Authorization - RBAC
  • Loading branch information
ciprianjichici authored May 16, 2024
2 parents 02481ac + 96fda10 commit 4ca818d
Show file tree
Hide file tree
Showing 58 changed files with 1,312 additions and 393 deletions.
78 changes: 53 additions & 25 deletions src/dotnet/Agent/ResourceProviders/AgentResourceProviderService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
using FluentValidation;
using FoundationaLLM.Agent.Models.Resources;
using FoundationaLLM.Common.Constants;
using FoundationaLLM.Common.Constants.Authorization;
using FoundationaLLM.Common.Constants.Configuration;
using FoundationaLLM.Common.Constants.ResourceProviders;
using FoundationaLLM.Common.Exceptions;
using FoundationaLLM.Common.Interfaces;
using FoundationaLLM.Common.Models.Authentication;
using FoundationaLLM.Common.Models.Authorization;
using FoundationaLLM.Common.Models.Configuration.Instance;
using FoundationaLLM.Common.Models.Events;
using FoundationaLLM.Common.Models.ResourceProviders;
Expand All @@ -18,6 +20,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Collections.Concurrent;
using System.Data;
using System.Text;
using System.Text.Json;

Expand Down Expand Up @@ -98,26 +101,24 @@ await _storageService.WriteFileAsync(
protected override async Task<object> GetResourcesAsync(ResourcePath resourcePath, UnifiedUserIdentity userIdentity) =>
resourcePath.ResourceTypeInstances[0].ResourceType switch
{
AgentResourceTypeNames.Agents => await LoadAgents(resourcePath.ResourceTypeInstances[0]),
AgentResourceTypeNames.Agents => await LoadAgents(resourcePath.ResourceTypeInstances[0], userIdentity),
_ => throw new ResourceProviderException($"The resource type {resourcePath.ResourceTypeInstances[0].ResourceType} is not supported by the {_name} resource provider.",
StatusCodes.Status400BadRequest)
};

#region Helpers for GetResourcesAsyncInternal

private async Task<List<AgentBase>> LoadAgents(ResourceTypeInstance instance)
private async Task<List<ResourceProviderGetResult<AgentBase>>> LoadAgents(ResourceTypeInstance instance, UnifiedUserIdentity userIdentity)
{
var agents = new List<AgentBase>();

if (instance.ResourceId == null)
{
return
[
.. (await Task.WhenAll(
_agentReferences.Values
.Where(ar => !ar.Deleted)
.Select(ar => LoadAgent(ar))))
.Where(agent => agent != null)
.ToList()
];
agents = (await Task.WhenAll(_agentReferences.Values
.Where(ar => !ar.Deleted)
.Select(ar => LoadAgent(ar))))
.Where(agent => agent != null)
.ToList();
}
else
{
Expand All @@ -127,24 +128,49 @@ private async Task<List<AgentBase>> LoadAgents(ResourceTypeInstance instance)
agent = await LoadAgent(null, instance.ResourceId);
if (agent != null)
{
return [agent];
agents.Add(agent);
}
return [];
}
if (agentReference.Deleted)
else
{
throw new ResourceProviderException($"Could not locate the {instance.ResourceId} agent resource.",
StatusCodes.Status404NotFound);
if (agentReference.Deleted)
{
throw new ResourceProviderException($"Could not locate the {instance.ResourceId} agent resource.",
StatusCodes.Status404NotFound);
}

agent = await LoadAgent(agentReference);
if (agent != null)
{
agents.Add(agent);
}
}
}

agent = await LoadAgent(agentReference);
var rolesWithActions = await _authorizationService.ProcessRoleAssignmentsWithActionsRequest(
_instanceSettings.Id,
new RoleAssignmentsWithActionsRequest()
{
Scopes = agents.Select(x => x.ObjectId!).ToList(),
PrincipalId = userIdentity.UserId!,
SecurityGroupIds = userIdentity.GroupIds
});

if (agent != null)
var results = new List<ResourceProviderGetResult<AgentBase>>();
foreach (var agent in agents)
{
if (rolesWithActions[agent.ObjectId!].Actions.Contains(AuthorizableActionNames.FoundationaLLM_Agent_Agents_Read))
{
return [agent];
results.Add(new ResourceProviderGetResult<AgentBase>()
{
Resource = agent,
Actions = rolesWithActions[agent.ObjectId!].Actions,
Roles = rolesWithActions[agent.ObjectId!].Roles
});
}
return [];
}

return results;
}

private async Task<AgentBase?> LoadAgent(AgentReference? agentReference, string? resourceId = null)
Expand All @@ -162,13 +188,14 @@ private async Task<List<AgentBase>> LoadAgents(ResourceTypeInstance instance)
if (await _storageService.FileExistsAsync(_storageContainerName, agentReference.Filename, default))
{
var fileContent = await _storageService.ReadFileAsync(_storageContainerName, agentReference.Filename, default);

var agent = JsonSerializer.Deserialize(
Encoding.UTF8.GetString(fileContent.ToArray()),
agentReference.AgentType,
_serializerSettings) as AgentBase
?? throw new ResourceProviderException($"Failed to load the agent {agentReference.Name}.",
StatusCodes.Status400BadRequest);

if (!string.IsNullOrWhiteSpace(resourceId))
{
// The agent file exists, but the agent reference is not in the dictionary. Update the dictionary with the missing reference.
Expand Down Expand Up @@ -291,7 +318,8 @@ await _storageService.WriteFileAsync(

return new ResourceProviderUpsertResult
{
ObjectId = (agent as AgentBase)!.ObjectId
ObjectId = agent!.ObjectId,
ResourceExists = existingAgentReference != null
};
}

Expand Down Expand Up @@ -457,9 +485,9 @@ private async Task HandleAgentResourceProviderEvent(CloudEvent e)
Deleted = false
};

var agent = await LoadAgent(agentReference);
agentReference.Name = agent.Name;
agentReference.Type = agent.Type;
var getAgentResult = await LoadAgent(agentReference, null);
agentReference.Name = getAgentResult.Name;
agentReference.Type = getAgentResult.Type;

_agentReferences.AddOrUpdate(
agentReference.Name,
Expand Down
9 changes: 0 additions & 9 deletions src/dotnet/Authorization/Authorization.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@
</ItemGroup>

<ItemGroup>
<None Update="Constants\AuthorizableActionNames.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>AuthorizableActionNames.cs</LastGenOutput>
</None>
<None Update="Models\AuthorizableActions.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>AuthorizableActions.cs</LastGenOutput>
Expand All @@ -36,11 +32,6 @@
</ItemGroup>

<ItemGroup>
<Compile Update="Constants\AuthorizableActionNames.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>AuthorizableActionNames.tt</DependentUpon>
</Compile>
<Compile Update="Models\AuthorizableActions.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
Expand Down
Loading

0 comments on commit 4ca818d

Please sign in to comment.