Skip to content

Commit 77a5f11

Browse files
authored
Merge pull request #2 from tglima/v0.2
Release v0.2
2 parents e2dcb66 + 63af120 commit 77a5f11

File tree

12 files changed

+314
-102
lines changed

12 files changed

+314
-102
lines changed

.vscode/launch.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
1717
},
1818
"env": {
19-
"ASPNETCORE_ENVIRONMENT": "Development"
19+
"ASPNETCORE_ENVIRONMENT": "Development",
20+
"API_KEY": "77be91d8-4bb1ba8e27a9"
2021
},
2122
"sourceFileMap": {
2223
"/Views": "${workspaceFolder}/Views"

.vscode/tasks.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
{
22
"version": "2.0.0",
33
"tasks": [
4+
{
5+
"label": "prebuild",
6+
"command": "dotnet",
7+
"type": "process",
8+
"args": [
9+
"clean",
10+
"${workspaceFolder}/SlnRestapiDotnetCore6.sln"
11+
],
12+
"problemMatcher": "$msCompile"
13+
},
414
{
515
"label": "build",
16+
"dependsOrder": "sequence",
17+
"dependsOn": "prebuild",
618
"command": "dotnet",
719
"type": "process",
820
"args": [

Helpers/Constant.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,22 @@ namespace WebApi.Helpers
1111
public class Constant
1212
{
1313
public static readonly string API_KEY = "API-KEY";
14+
public static readonly string APP_JSON = "application/json";
1415
public static readonly string OK = "OK";
1516
public static readonly string MsgStatus400 = "Ocorreu uma falha/erro na sua requisição. Reveja os dados enviados e tente novamente!";
1617
public static readonly string MsgStatus401 = "Credenciais inválidas ou ausentes";
1718
public static readonly string MsgStatus404 = "Item não encontrado!";
1819
public static readonly string MsgStatus429 = "Limite de requisições ultrapassado, por favor, aguarde.";
1920
public static readonly string MsgStatus500 = "Erro interno no servidor!";
21+
public static readonly string SwaggerTitle = "Rest API";
22+
public static readonly string SwaggerDescription = "Swagger dos principais endpoints da API";
23+
public static readonly string SwaggerContactName = "API Support - Website";
24+
public static readonly string SwaggerContactUrl = "https://github.com/tglima/restapi-dotnetcore6";
25+
public static readonly string SwaggerLicenseName = "MIT";
26+
public static readonly string SwaggerLicenseUrl = "https://github.com/tglima/restapi-dotnetcore6/blob/main/LICENSE";
27+
public static readonly string SwaggerSecurityDescription = "Chave de acesso individual disponibilizado para acessar a API";
28+
public static readonly string SwaggerSecurityScheme = "ApiKeyScheme";
29+
2030
}
2131
}
2232

Helpers/DbSQLiteContext.cs

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Threading.Tasks;
5-
6-
using System.Data;
71
using Dapper;
2+
using System.Data;
3+
using WebApi.Models.DTO;
84
using Microsoft.Data.Sqlite;
95

106
namespace WebApi.Helpers
@@ -82,5 +78,44 @@ idx_code_event_error ON log_error
8278
await connection.ExecuteAsync(createIndexCodeEvent);
8379
}
8480
}
81+
82+
public async Task InsertLog(LogDTO logDTO)
83+
{
84+
using var connection = CreateConnection();
85+
86+
var sqlInsert = @"INSERT INTO log_event
87+
(code_event, api_key, dt_start, dt_finish, request_data, response_data, code_status)
88+
VALUES (@CodeEvent, @ApiKey, @DtStart, @DtFinish, @RequestData, @ResponseData, @CodeStatus)";
89+
90+
await connection.ExecuteAsync(sqlInsert, new
91+
{
92+
logDTO.CodeEvent,
93+
logDTO.ApiKey,
94+
logDTO.DtStart,
95+
logDTO.DtFinish,
96+
logDTO.RequestData,
97+
logDTO.ResponseData,
98+
logDTO.CodeStatus
99+
});
100+
}
101+
102+
103+
public async Task InsertLogError(LogErrorDTO logError)
104+
{
105+
using var connection = CreateConnection();
106+
107+
var sqlInsert = @"INSERT INTO log_error
108+
(code_event, dt_register, method, exception_message, stack_trace)
109+
VALUES (@CodeEvent, @DtRegister, @Method, @ExceptionMessage, @StackTrace)";
110+
111+
await connection.ExecuteAsync(sqlInsert, new
112+
{
113+
logError.CodeEvent,
114+
logError.DtRegister,
115+
logError.Method,
116+
logError.ExceptionMessage,
117+
logError.StackTrace
118+
});
119+
}
85120
}
86121
}

Middlewares/ApiHandlerMiddleware.cs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
using WebApi.Models.API;
3+
using WebApi.Models.DTO;
4+
using WebApi.Helpers;
5+
using WebApi.Services;
6+
7+
namespace WebApi.Middlewares
8+
{
9+
10+
public static class ApiHandlerMiddlewareExtensions
11+
{
12+
public static IApplicationBuilder UseApiHandlerMiddleware(this IApplicationBuilder builder)
13+
{
14+
return builder.UseMiddleware<ApiHandlerMiddleware>();
15+
}
16+
}
17+
18+
public class ApiHandlerMiddleware
19+
{
20+
private readonly RequestDelegate _next;
21+
22+
public ApiHandlerMiddleware(RequestDelegate next)
23+
{
24+
_next = next;
25+
}
26+
27+
28+
public async Task InvokeAsync(HttpContext context, LogService logService)
29+
{
30+
await logService.SetRequestData(context);
31+
32+
var respValidateApiKey = ValidateApiKey(context, logService.LogDTO);
33+
34+
logService.LogDTO.Methods.Add(respValidateApiKey);
35+
36+
string responseBody = string.Empty;
37+
38+
if (respValidateApiKey.StatusCode.Equals(StatusCodeApi.UNNAUTHORIZED))
39+
{
40+
context.Response.StatusCode = (int)respValidateApiKey.StatusCode;
41+
context.Response.ContentType = Constant.APP_JSON;
42+
responseBody = AppHelper.ToJSON(respValidateApiKey.Returnbject);
43+
await context.Response.WriteAsJsonAsync(respValidateApiKey.Returnbject);
44+
}
45+
else
46+
{
47+
48+
// A partir deste ponto, seria após a execução do controller
49+
try
50+
{
51+
using var memoryStream = new MemoryStream();
52+
var originalBody = context.Response.Body;
53+
context.Response.Body = memoryStream;
54+
55+
await _next(context);
56+
57+
memoryStream.Seek(0, SeekOrigin.Begin);
58+
responseBody = new StreamReader(memoryStream).ReadToEnd();
59+
}
60+
catch (Exception ex)
61+
{
62+
await logService.SaveLogError(new LogErrorDTO(ex, "Middleware.InvokeAsync"));
63+
var response = context.Response;
64+
response.ContentType = Constant.APP_JSON; ;
65+
var respError = new ApiResponseFail(Constant.MsgStatus500, logService.LogDTO.CodeEvent);
66+
response.StatusCode = (int)StatusCodeApi.ERROR;
67+
context.Response.ContentType = Constant.APP_JSON;
68+
responseBody = AppHelper.ToJSON(respError);
69+
70+
await context.Response.WriteAsJsonAsync(respError);
71+
}
72+
}
73+
74+
logService.SetResponseData(context.Response, responseBody);
75+
await logService.SaveLog();
76+
}
77+
78+
79+
private static ReturnDTO ValidateApiKey(HttpContext context, LogDTO logDTO)
80+
{
81+
82+
bool isValidApiKey = true;
83+
84+
var returnDTO = new ReturnDTO
85+
{
86+
NmMethod = "ValidateApiKey"
87+
};
88+
89+
if (context.GetEndpoint()?.Metadata.GetMetadata<IAllowAnonymous>() == null)
90+
{
91+
92+
var apiKeyFromEnv = Environment.GetEnvironmentVariable("API_KEY") ?? string.Empty;
93+
string[] listApiKeyValid = apiKeyFromEnv.Split(';');
94+
95+
if (string.IsNullOrEmpty(logDTO.ApiKey))
96+
{
97+
returnDTO.Info.Add("Api Key was not provided");
98+
isValidApiKey = false;
99+
}
100+
101+
102+
if (!string.IsNullOrEmpty(logDTO.ApiKey) && !Array.Exists(listApiKeyValid, apikey => logDTO.ApiKey.Equals(apikey)))
103+
{
104+
returnDTO.Info.Add("Unauthorized key");
105+
isValidApiKey = false;
106+
}
107+
}
108+
109+
110+
returnDTO.StatusCode = isValidApiKey ? StatusCodeApi.SUCCESS : StatusCodeApi.UNNAUTHORIZED;
111+
returnDTO.Returnbject = isValidApiKey ? null : new ApiResponseFail(Constant.MsgStatus401, logDTO.CodeEvent);
112+
113+
return returnDTO;
114+
}
115+
}
116+
}

Middlewares/ApiKeyMiddleware.cs

Lines changed: 0 additions & 77 deletions
This file was deleted.

Models/API/DefRespFail.cs renamed to Models/API/ApiResponseFail.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22

33
namespace WebApi.Models.API
44
{
5-
public class DefRespFail : ApiBase
5+
public class ApiResponseFail : ApiBase
66
{
77

8-
public DefRespFail()
8+
public ApiResponseFail()
99
{
1010
this.Messages = new();
1111
}
1212

13-
public DefRespFail(string Message)
13+
public ApiResponseFail(string Message, string? CodeEvent)
1414
{
15+
16+
this.CodeEvent = CodeEvent ?? string.Empty;
17+
1518
this.Messages = new()
1619
{
1720
Message

Models/DTO/LogErrorDTO.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ namespace WebApi.Models.DTO
55
{
66
public class LogErrorDTO : ApiBase
77
{
8+
public LogErrorDTO() { }
89

9-
public LogErrorDTO()
10+
public LogErrorDTO(Exception exception, string method)
1011
{
11-
this.DtRegister = AppHelper.GetDateNow();
12+
this.Method = method;
13+
this.ExceptionMessage = exception.Message;
14+
this.StackTrace = exception.StackTrace ?? string.Empty;
1215
}
1316

14-
public string DtRegister { get; set; }
17+
public string DtRegister = AppHelper.GetDateNow();
1518
public string Method = string.Empty;
1619
public string ExceptionMessage = string.Empty;
1720
public string StackTrace = string.Empty;

0 commit comments

Comments
 (0)