Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/adminapi23-rc.0' into ADMINAPI-1090
Browse files Browse the repository at this point in the history
  • Loading branch information
jagudelo-gap committed Nov 20, 2024
2 parents 34cd4dd + 250e8ba commit 1865407
Show file tree
Hide file tree
Showing 73 changed files with 2,006 additions and 275 deletions.
97 changes: 97 additions & 0 deletions .github/workflows/on-pullrequest-dockerfile-ac.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# SPDX-License-Identifier: Apache-2.0
# Licensed to the Ed-Fi Alliance under one or more agreements.
# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
# See the LICENSE and NOTICES files in the project root for more information.

name: On Pull Request - Dockerfile - Admin Console

on:
push:
branches:
- adminapi23-rc.*
pull_request:
branches:
- adminapi23-rc.*
workflow_dispatch:

env:
DOCKER_USERNAME: ${{ vars.DOCKER_USERNAME }}
DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }}
IMAGE_NAME: ${{ vars.IMAGE_NAME }}

permissions: read-all

jobs:
docker-analysis:
runs-on: ubuntu-latest
permissions:
security-events: write
pull-requests: write
strategy:
fail-fast: false
matrix:
dockerfile:
[
{ name: "development", path: "Docker/dev.pgsql.Dockerfile", type: "local" }
]
steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Set IMAGE_TAG
id: set-image-tag
run: |
if [ "${{ github.event_name }}" == "pull_request" ]; then
echo "IMAGE_TAG=${{ github.base_ref }}" >> $GITHUB_ENV
else
echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV
fi
- name: Copy application folder to docker context
if: ${{ matrix.dockerfile.type == 'local' }}
run: |
mkdir Docker/Application
cp -r ./Application/EdFi.Ods.AdminApi ./Docker/Application
cp -r ./Application/EdFi.Ods.AdminApi.AdminConsole ./Docker/Application
cp ./Application/NuGet.Config ./Docker/Application
- uses: hadolint/hadolint-action@54c9adbab1582c2ef04b2016b760714a4bfde3cf # v3.1.0
name: Run Linter on ${{ matrix.dockerfile.name }} Dockerfile
with:
dockerfile: ${{ matrix.dockerfile.path }}
failure-threshold: error

- name: Log in to Docker Hub
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ env.DOCKER_HUB_TOKEN }}

- name: Build
run: |
path=${{matrix.dockerfile.path}}
folder=${path%/*}
cd $folder
dockerfile=$(echo ${{matrix.dockerfile.path}} | awk -F"/" '{print $NF}')
docker build -f $dockerfile -t ${{ matrix.dockerfile.name }} --build-arg="VERSION=${{ env.IMAGE_TAG }}" .
- name: Analyze
uses: docker/scout-action@67eb1afe777307506aaecb9acd9a0e0389cb99ae # v1.5.0
with:
command: cves
image: local://${{ matrix.dockerfile.name }}
sarif-file: sarif-${{ matrix.dockerfile.name }}.output.json
summary: true

- name: Push Image on Docker Hub
run: |
docker image tag ${{ matrix.dockerfile.name }} ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
docker push ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
- name: Upload SARIF result
id: upload-sarif
if: ${{ github.event_name != 'pull_request_target' }}
uses: github/codeql-action/upload-sarif@cf7e9f23492505046de9a37830c3711dd0f25bb3 #codeql-bundle-v2.16.2
with:
sarif_file: sarif-${{ matrix.dockerfile.name }}.output.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// See the LICENSE and NOTICES files in the project root for more information.
using System.Text.Json;
using AutoMapper;
using EdFi.Ods.AdminApi.AdminConsole.Infrastructure.DataAccess.Models;
using EdFi.Ods.AdminApi.AdminConsole.Infrastructure.Services.HealthChecks.Queries;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
Expand All @@ -24,16 +25,16 @@ public void MapEndpoints(IEndpointRouteBuilder endpoints)
internal async Task<IResult> GetHealthcheck(IMapper mapper, IGetHealthCheckQuery getHealthCheckQuery, int tenantId)
{
var healthChecks = await getHealthCheckQuery.Execute(tenantId);
var model = mapper.Map<HealthCheckModel>(healthChecks);
string healthCheckModel = JsonSerializer.Serialize(model);
return Results.Ok(healthCheckModel);
if(healthChecks != null)
{
return Results.Ok(healthChecks);
}
return Results.NotFound();
}

internal async Task<IResult> GetHealthchecks(IMapper mapper, IGetHealthChecksQuery getHealthChecksQuery)
{
var healthChecks = await getHealthChecksQuery.Execute();
var model = mapper.Map<IEnumerable<HealthCheckModel>>(healthChecks);
string healthCheckModel = JsonSerializer.Serialize(model);
return Results.Ok(JsonDocument.Parse(healthCheckModel));
return Results.Ok(healthChecks);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public async Task<IResult> Execute(Validator validator, IAddInstanceCommand addI
await validator.GuardAsync(request);
var addedInstanceResult = await addInstanceCommand.Execute(request);

return Results.Created($"/instances/{addedInstanceResult.DocId}", addedInstanceResult);
return Results.Created($"/instances/{addedInstanceResult.TenantId}/{addedInstanceResult.DocId}", addedInstanceResult);
}

public class AddInstanceRequest : IAddInstanceModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using Newtonsoft.Json;

namespace EdFi.Ods.AdminApi.AdminConsole.Features.OdsInstances;
namespace EdFi.Ods.AdminApi.AdminConsole.Features.Instances;

public class InstanceModel
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Linq;
using System.Net.Http.Json;
using System.Text.Json;
using EdFi.Ods.AdminApi.AdminConsole.Features.OdsInstances;
using EdFi.Ods.AdminApi.AdminConsole.Infrastructure.DataAccess.Models;
using EdFi.Ods.AdminApi.AdminConsole.Infrastructure.Services.Instances.Queries;
using Microsoft.AspNetCore.Http;
Expand All @@ -22,25 +21,38 @@ public void MapEndpoints(IEndpointRouteBuilder endpoints)
AdminApiAdminConsoleEndpointBuilder.MapGet(endpoints, "/instances", GetInstances)
.BuildForVersions();

AdminApiAdminConsoleEndpointBuilder.MapGet(endpoints, "/instances/{id}", GetInstance)
AdminApiAdminConsoleEndpointBuilder.MapGet(endpoints, "/instances/{tenantId}/{id}", GetInstanceById)
.WithRouteOptions(b => b.WithResponse<InstanceModel>(200))
.BuildForVersions();

AdminApiAdminConsoleEndpointBuilder.MapGet(endpoints, "/instances/{tenantId}", GetInstancesByTenantId)
.WithRouteOptions(b => b.WithResponse<InstanceModel>(200))
.BuildForVersions();
}

internal async Task<IResult> GetInstances([FromServices] IGetInstancesQuery getInstancesQuery)
{
var instances = await getInstancesQuery.Execute();
IEnumerable<JsonDocument> instancesList = instances.Select(i => JsonDocument.Parse(i.Document));
return Results.Ok(instancesList);
return Results.Ok(instances);
}

internal async Task<IResult> GetInstance([FromServices] IGetInstanceQuery getInstanceQuery, int tenantId)
internal async Task<IResult> GetInstanceById([FromServices] IGetInstanceByIdQuery getInstanceQuery, int tenantId, int id)
{
var instance = await getInstanceQuery.Execute(tenantId);
var instance = await getInstanceQuery.Execute(tenantId, id);

if (instance != null)
return Results.Ok(JsonDocument.Parse(instance.Document));
return Results.Ok(instance);

return Results.NotFound();
}

internal async Task<IResult> GetInstancesByTenantId([FromServices] IGetInstancesByTenantIdQuery getInstancesQuery, int tenantId)
{
var instances = await getInstancesQuery.Execute(tenantId);
if (instances.Any())
{
return Results.Ok(instances);
}
return Results.NotFound();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// See the LICENSE and NOTICES files in the project root for more information.

using System.ComponentModel.DataAnnotations;
using EdFi.Ods.AdminApi.AdminConsole.Infrastructure.Services.Instances.Commands;
using EdFi.Ods.AdminApi.AdminConsole.Infrastructure.Services.Permissions.Commands;
using FluentValidation;
using Microsoft.AspNetCore.Http;
Expand All @@ -25,7 +26,7 @@ public async Task<IResult> Execute(Validator validator, IAddPermissionCommand ad
await validator.GuardAsync(request);
var addedPermissionResult = await addPermissionCommand.Execute(request);

return Results.Created($"/permissions/{addedPermissionResult.DocId}", addedPermissionResult);
return Results.Created($"/permissions/{addedPermissionResult.TenantId}/{addedPermissionResult.DocId}", addedPermissionResult);
}

public class AddPermissionRequest : IAddPermissionModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
// See the LICENSE and NOTICES files in the project root for more information.

using System.Dynamic;
using EdFi.Ods.AdminApi.AdminConsole.Features.OdsInstances;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text.Json;
using EdFi.Ods.AdminApi.AdminConsole.Features.Permissions;
using EdFi.Ods.AdminApi.AdminConsole.Infrastructure.DataAccess.Models;
Expand All @@ -23,25 +24,38 @@ public void MapEndpoints(IEndpointRouteBuilder endpoints)
AdminApiAdminConsoleEndpointBuilder.MapGet(endpoints, "/permissions", GetPermissions)
.BuildForVersions();

AdminApiAdminConsoleEndpointBuilder.MapGet(endpoints, "/permissions/{id}", GetPermission)
AdminApiAdminConsoleEndpointBuilder.MapGet(endpoints, "/permissions/{tenantId}/{id}", GetPermissionById)
.WithRouteOptions(b => b.WithResponse<PermissionModel>(200))
.BuildForVersions();

AdminApiAdminConsoleEndpointBuilder.MapGet(endpoints, "/permissions/{tenantId}", GetPermissionsByTenantId)
.WithRouteOptions(b => b.WithResponse<PermissionModel>(200))
.BuildForVersions();
}

internal async Task<IResult> GetPermissions([FromServices] IGetPermissionsQuery getPermissionQuery)
{
var permissions = await getPermissionQuery.Execute();
IEnumerable<JsonDocument> permissionsList = permissions.Select(i => JsonDocument.Parse(i.Document));
return Results.Ok(permissionsList);
return Results.Ok(permissions);
}

internal async Task<IResult> GetPermission([FromServices] IGetPermissionQuery getPermissionQuery, int tenantId)
internal async Task<IResult> GetPermissionById([FromServices] IGetPermissionByIdQuery getPermissionQuery, int tenantId, int id)
{
var permission = await getPermissionQuery.Execute(tenantId);
var permission = await getPermissionQuery.Execute(tenantId, id);

if (permission != null)
return Results.Ok(JsonDocument.Parse(permission.Document));
return Results.Ok(permission);

return Results.NotFound();
}

internal async Task<IResult> GetPermissionsByTenantId([FromServices] IGetPermissionsByTenantIdQuery getPermissionQuery, int tenantId)
{
var permissions = await getPermissionQuery.Execute(tenantId);
if (permissions.Any())
{
return Results.Ok(permissions);
}
return Results.NotFound();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-License-Identifier: Apache-2.0
// Licensed to the Ed-Fi Alliance under one or more agreements.
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
// See the LICENSE and NOTICES files in the project root for more information.

using System.ComponentModel.DataAnnotations;
using EdFi.Ods.AdminApi.AdminConsole.Infrastructure.Services.Steps.Commands;
using FluentValidation;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;

namespace EdFi.Ods.AdminApi.AdminConsole.Features.Steps;

public class AddStep: IFeature
{
public void MapEndpoints(IEndpointRouteBuilder endpoints)
{
AdminApiAdminConsoleEndpointBuilder.MapPost(endpoints, "/steps", Execute)
.WithRouteOptions(b => b.WithResponseCode(201))
.BuildForVersions();
}

public async Task<IResult> Execute(Validator validator, IAddStepCommand addStepCommand, AddStepRequest request)
{
await validator.GuardAsync(request);
var addedStepResult = await addStepCommand.Execute(request);

return Results.Created($"/steps/{addedStepResult.TenantId}/{addedStepResult.DocId}", addedStepResult);
}

public class AddStepRequest : IAddStepModel
{
[Required]
public int InstanceId { get; set; }
public int? EdOrgId { get; set; }
[Required]
public int TenantId { get; set; }
[Required]
public string Document { get; set; }
}

public class Validator : AbstractValidator<AddStepRequest>
{
public Validator()
{
RuleFor(m => m.InstanceId)
.NotNull();

RuleFor(m => m.EdOrgId)
.NotNull();

RuleFor(m => m.Document)
.NotNull()
.NotEmpty()
.Must(BeValidDocument).WithMessage("Document must be a valid JSON.");
}

private bool BeValidDocument(string document)
{
try
{
Newtonsoft.Json.Linq.JToken.Parse(document);
return true;
}
catch (Newtonsoft.Json.JsonReaderException)
{
return false;
}
}
}
}
Loading

0 comments on commit 1865407

Please sign in to comment.