forked from balta-io/2811
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
525d9de
commit f4e349a
Showing
34 changed files
with
1,787 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
|
||
namespace Blog.Attributes; | ||
|
||
[AttributeUsage(validOn: AttributeTargets.Class | AttributeTargets.Method)] | ||
public class ApiKeyAttribute : Attribute, IAsyncActionFilter | ||
{ | ||
public async Task OnActionExecutionAsync( | ||
ActionExecutingContext context, | ||
ActionExecutionDelegate next) | ||
{ | ||
if (!context.HttpContext.Request.Query.TryGetValue(Configuration.ApiKeyName, out var extractedApiKey)) | ||
{ | ||
context.Result = new ContentResult() | ||
{ | ||
StatusCode = 401, | ||
Content = "ApiKey não encontrada" | ||
}; | ||
return; | ||
} | ||
|
||
if (!Configuration.ApiKey.Equals(extractedApiKey)) | ||
{ | ||
context.Result = new ContentResult() | ||
{ | ||
StatusCode = 403, | ||
Content = "Acesso não autorizado" | ||
}; | ||
return; | ||
} | ||
|
||
await next(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.11" /> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.11"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.11" /> | ||
<PackageReference Include="SecureIdentity" Version="1.0.2" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Folder Include="wwwroot\images" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.0.31815.197 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog", "Blog.csproj", "{5AF32844-E01D-4B13-BF2E-359F82C5CC00}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{5AF32844-E01D-4B13-BF2E-359F82C5CC00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{5AF32844-E01D-4B13-BF2E-359F82C5CC00}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{5AF32844-E01D-4B13-BF2E-359F82C5CC00}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{5AF32844-E01D-4B13-BF2E-359F82C5CC00}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {0A38ABAF-B508-44E9-ABD0-ECE25A043CE0} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
namespace Blog; | ||
|
||
public static class Configuration | ||
{ | ||
public static string JwtKey = "ZmVkYWY3ZDg4NjNiNDhlMTk3YjkyODdkNDkyYjcwOGU="; | ||
public static string ApiKeyName = "api_key"; | ||
public static string ApiKey = "curso_api_IlTevUM/z0ey3NwCV/unWg=="; | ||
public static SmtpConfiguration Smtp = new(); | ||
|
||
public class SmtpConfiguration | ||
{ | ||
public string Host { get; set; } | ||
public int Port { get; set; } = 25; | ||
public string UserName { get; set; } | ||
public string Password { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
using System.Text.RegularExpressions; | ||
using Blog.Data; | ||
using Blog.Extensions; | ||
using Blog.Models; | ||
using Blog.Services; | ||
using Blog.ViewModels; | ||
using Blog.ViewModels.Accounts; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.EntityFrameworkCore; | ||
using SecureIdentity.Password; | ||
|
||
namespace Blog.Controllers; | ||
|
||
[ApiController] | ||
public class AccountController : ControllerBase | ||
{ | ||
[HttpPost("v1/accounts/")] | ||
public async Task<IActionResult> Post( | ||
[FromBody] RegisterViewModel model, | ||
[FromServices] BlogDataContext context, | ||
[FromServices] EmailService emailService) | ||
{ | ||
if (!ModelState.IsValid) | ||
return BadRequest(new ResultViewModel<string>(ModelState.GetErrors())); | ||
|
||
var user = new User | ||
{ | ||
Name = model.Name, | ||
Email = model.Email, | ||
Slug = model.Email.Replace("@", "-").Replace(".", "-") | ||
}; | ||
|
||
var password = PasswordGenerator.Generate(25); | ||
user.PasswordHash = PasswordHasher.Hash(password); | ||
|
||
try | ||
{ | ||
await context.Users.AddAsync(user); | ||
await context.SaveChangesAsync(); | ||
|
||
emailService.Send(user.Name, user.Email, "Bem vindo ao blog!", $"Sua senha é {password}"); | ||
return Ok(new ResultViewModel<dynamic>(new | ||
{ | ||
user = user.Email, password | ||
})); | ||
} | ||
catch (DbUpdateException) | ||
{ | ||
return StatusCode(400, new ResultViewModel<string>("05X99 - Este E-mail já está cadastrado")); | ||
} | ||
catch | ||
{ | ||
return StatusCode(500, new ResultViewModel<string>("05X04 - Falha interna no servidor")); | ||
} | ||
} | ||
|
||
[HttpPost("v1/accounts/login")] | ||
public async Task<IActionResult> Login( | ||
[FromBody] LoginViewModel model, | ||
[FromServices] BlogDataContext context, | ||
[FromServices] TokenService tokenService) | ||
{ | ||
if (!ModelState.IsValid) | ||
return BadRequest(new ResultViewModel<string>(ModelState.GetErrors())); | ||
|
||
var user = await context | ||
.Users | ||
.AsNoTracking() | ||
.Include(x => x.Roles) | ||
.FirstOrDefaultAsync(x => x.Email == model.Email); | ||
|
||
if (user == null) | ||
return StatusCode(401, new ResultViewModel<string>("Usuário ou senha inválidos")); | ||
|
||
if (!PasswordHasher.Verify(user.PasswordHash, model.Password)) | ||
return StatusCode(401, new ResultViewModel<string>("Usuário ou senha inválidos")); | ||
|
||
try | ||
{ | ||
var token = tokenService.GenerateToken(user); | ||
return Ok(new ResultViewModel<string>(token, null)); | ||
} | ||
catch | ||
{ | ||
return StatusCode(500, new ResultViewModel<string>("05X04 - Falha interna no servidor")); | ||
} | ||
} | ||
|
||
[Authorize] | ||
[HttpPost("v1/accounts/upload-image")] | ||
public async Task<IActionResult> UploadImage( | ||
[FromBody] UploadImageViewModel model, | ||
[FromServices] BlogDataContext context) | ||
{ | ||
var fileName = $"{Guid.NewGuid().ToString()}.jpg"; | ||
var data = new Regex(@"^data:image\/[a-z]+;base64,").Replace(model.Base64Image, ""); | ||
var bytes = Convert.FromBase64String(data); | ||
|
||
try | ||
{ | ||
await System.IO.File.WriteAllBytesAsync($"wwwroot/images/{fileName}", bytes); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return StatusCode(500, new ResultViewModel<string>("05X04 - Falha interna no servidor")); | ||
} | ||
|
||
var user = await context | ||
.Users | ||
.FirstOrDefaultAsync(x => x.Email == User.Identity.Name); | ||
|
||
if (user == null) | ||
return NotFound(new ResultViewModel<Category>("Usuário não encontrado")); | ||
|
||
user.Image = $"https://localhost:0000/images/{fileName}"; | ||
try | ||
{ | ||
context.Users.Update(user); | ||
await context.SaveChangesAsync(); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return StatusCode(500, new ResultViewModel<string>("05X04 - Falha interna no servidor")); | ||
} | ||
|
||
return Ok(new ResultViewModel<string>("Imagem alterada com sucesso!", null)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
using Blog.Data; | ||
using Blog.Extensions; | ||
using Blog.Models; | ||
using Blog.ViewModels; | ||
using Blog.ViewModels.Categories; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.EntityFrameworkCore; | ||
|
||
namespace Blog.Controllers | ||
{ | ||
[ApiController] | ||
public class CategoryController : ControllerBase | ||
{ | ||
[HttpGet("v1/categories")] | ||
public async Task<IActionResult> GetAsync( | ||
[FromServices] BlogDataContext context) | ||
{ | ||
try | ||
{ | ||
var categories = await context.Categories.ToListAsync(); | ||
return Ok(new ResultViewModel<List<Category>>(categories)); | ||
} | ||
catch | ||
{ | ||
return StatusCode(500, new ResultViewModel<List<Category>>("05X04 - Falha interna no servidor")); | ||
} | ||
} | ||
|
||
[HttpGet("v1/categories/{id:int}")] | ||
public async Task<IActionResult> GetByIdAsync( | ||
[FromRoute] int id, | ||
[FromServices] BlogDataContext context) | ||
{ | ||
try | ||
{ | ||
var category = await context | ||
.Categories | ||
.FirstOrDefaultAsync(x => x.Id == id); | ||
|
||
if (category == null) | ||
return NotFound(new ResultViewModel<Category>("Conteúdo não encontrado")); | ||
|
||
return Ok(new ResultViewModel<Category>(category)); | ||
} | ||
catch | ||
{ | ||
return StatusCode(500, new ResultViewModel<Category>("Falha interna no servidor")); | ||
} | ||
} | ||
|
||
[HttpPost("v1/categories")] | ||
public async Task<IActionResult> PostAsync( | ||
[FromBody] EditorCategoryViewModel model, | ||
[FromServices] BlogDataContext context) | ||
{ | ||
if (!ModelState.IsValid) | ||
return BadRequest(new ResultViewModel<Category>(ModelState.GetErrors())); | ||
|
||
try | ||
{ | ||
var category = new Category | ||
{ | ||
Id = 0, | ||
Name = model.Name, | ||
Slug = model.Slug.ToLower(), | ||
}; | ||
await context.Categories.AddAsync(category); | ||
await context.SaveChangesAsync(); | ||
|
||
return Created($"v1/categories/{category.Id}", new ResultViewModel<Category>(category)); | ||
} | ||
catch (DbUpdateException ex) | ||
{ | ||
return StatusCode(500, new ResultViewModel<Category>("05XE9 - Não foi possível incluir a categoria")); | ||
} | ||
catch | ||
{ | ||
return StatusCode(500, new ResultViewModel<Category>("05X10 - Falha interna no servidor")); | ||
} | ||
} | ||
|
||
[HttpPut("v1/categories/{id:int}")] | ||
public async Task<IActionResult> PutAsync( | ||
[FromRoute] int id, | ||
[FromBody] EditorCategoryViewModel model, | ||
[FromServices] BlogDataContext context) | ||
{ | ||
try | ||
{ | ||
var category = await context | ||
.Categories | ||
.FirstOrDefaultAsync(x => x.Id == id); | ||
|
||
if (category == null) | ||
return NotFound(new ResultViewModel<Category>("Conteúdo não encontrado")); | ||
|
||
category.Name = model.Name; | ||
category.Slug = model.Slug; | ||
|
||
context.Categories.Update(category); | ||
await context.SaveChangesAsync(); | ||
|
||
return Ok(new ResultViewModel<Category>(category)); | ||
} | ||
catch (DbUpdateException ex) | ||
{ | ||
return StatusCode(500, new ResultViewModel<Category>("05XE8 - Não foi possível alterar a categoria")); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return StatusCode(500, new ResultViewModel<Category>("05X11 - Falha interna no servidor")); | ||
} | ||
} | ||
|
||
[HttpDelete("v1/categories/{id:int}")] | ||
public async Task<IActionResult> DeleteAsync( | ||
[FromRoute] int id, | ||
[FromServices] BlogDataContext context) | ||
{ | ||
try | ||
{ | ||
var category = await context | ||
.Categories | ||
.FirstOrDefaultAsync(x => x.Id == id); | ||
|
||
if (category == null) | ||
return NotFound(new ResultViewModel<Category>("Conteúdo não encontrado")); | ||
|
||
context.Categories.Remove(category); | ||
await context.SaveChangesAsync(); | ||
|
||
return Ok(new ResultViewModel<Category>(category)); | ||
} | ||
catch (DbUpdateException ex) | ||
{ | ||
return StatusCode(500, new ResultViewModel<Category>("05XE7 - Não foi possível excluir a categoria")); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return StatusCode(500, new ResultViewModel<Category>("05X12 - Falha interna no servidor")); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace Blog.Controllers | ||
{ | ||
[ApiController] | ||
[Route("")] | ||
public class HomeController : ControllerBase | ||
{ | ||
[HttpGet("")] | ||
public IActionResult Get() | ||
{ | ||
return Ok(); | ||
} | ||
} | ||
} |
Oops, something went wrong.