Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
404 changes: 404 additions & 0 deletions .gitignore

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions APIBook/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
35 changes: 35 additions & 0 deletions APIBook/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/APIBook/bin/Debug/net6.0/APIBook.dll",
"args": [],
"cwd": "${workspaceFolder}/APIBook",
"stopAtEntry": false,
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}
41 changes: 41 additions & 0 deletions APIBook/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/APIBook/APIBook.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/APIBook/APIBook.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/APIBook/APIBook.csproj"
],
"problemMatcher": "$msCompile"
}
]
}
31 changes: 31 additions & 0 deletions APIBook/APIBook.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33103.184
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APIBook", "APIBook\APIBook.csproj", "{3C79CF80-0AD9-42A5-8FA8-6B75170A037F}"
EndProject
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{E51AE39F-906B-43A0-B84C-87C090CBC6FB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3C79CF80-0AD9-42A5-8FA8-6B75170A037F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C79CF80-0AD9-42A5-8FA8-6B75170A037F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C79CF80-0AD9-42A5-8FA8-6B75170A037F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3C79CF80-0AD9-42A5-8FA8-6B75170A037F}.Release|Any CPU.Build.0 = Release|Any CPU
{E51AE39F-906B-43A0-B84C-87C090CBC6FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E51AE39F-906B-43A0-B84C-87C090CBC6FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E51AE39F-906B-43A0-B84C-87C090CBC6FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E51AE39F-906B-43A0-B84C-87C090CBC6FB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EB867682-F5B3-445D-887B-C39BEA7452A9}
EndGlobalSection
EndGlobal
36 changes: 36 additions & 0 deletions APIBook/APIBook/APIBook.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>ecb3b24a-4605-4a48-a09b-7da3b33965f5</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>

<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>

</Project>
46 changes: 46 additions & 0 deletions APIBook/APIBook/Authorization/Auth.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using APIBook.Repository;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace APIBook
{
public class JwtAuth
{
private readonly string _key;


public JwtAuth(string key)
{
_key = key;
}

public string Authenticate(string username, string password)
{
User user_loggin = UserRepository.Get(username, password); // Pegar o usuario do pseudo repositorio.


JwtSecurityTokenHandler token_handle = new JwtSecurityTokenHandler();

var token_key = Encoding.ASCII.GetBytes(_key);

SecurityTokenDescriptor token_descriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, user_loggin.Username), // objetos utilizado para formar a token unica do usuario.
new Claim(ClaimTypes.Role, user_loggin.Role)
}),
Expires = DateTime.UtcNow.AddHours(1), // limita a token por uma hora
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(token_key),
SecurityAlgorithms.HmacSha256Signature)
};

var token = token_handle.CreateToken(token_descriptor);

return token_handle.WriteToken(token); // trasnformar class da token em string
}
}
}
132 changes: 132 additions & 0 deletions APIBook/APIBook/Controller/BookController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using APIBook.Model;
using APIBook.Repository;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace APIBook.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class BookController : ControllerBase
{
private readonly JwtAuth _jwtAuthentication;
private readonly IBookRepository _bookRepository;
public BookController(IBookRepository bookRepository, JwtAuth auth)
{
_bookRepository = bookRepository;
_jwtAuthentication = auth;
}



// Qualquer usuario logado ou não pode utilizar
[HttpGet]
public async Task<ActionResult<Book>> GetBooks()
{
var b = await _bookRepository.Get(); // Pegando a lista de livros representado por b
if(b == null)
return NoContent();

return Ok(b.OrderBy(x => x.Title)); // Ordenar a ordem em Acresente pelo TITULO como julgado no teste
}


// Apenas usuarios autenticados podem usar
[Authorize]
[HttpGet("{id}")]
public async Task<ActionResult<Book>> GetBook(int id)
{
Book? book = await _bookRepository.GetById(id); // irar chamar a função de get by ID e procurar na DB

if (book == null) // Se nesse caso retornar nenhum livro a variavel nomeada book sera nulla nesse caso deve se esperar o retorno NotFound codigo 404
return NotFound();

return Ok(book); // Caso contrario e encontrar algum livro do ID em questão é necessario retornar o objeto ao usuario
}


[Authorize (Roles = "admin,user")]
[HttpGet("(Title){Title}")] // Esse argumento (Title) vai ser o indentificador da função para diferenciar a do ID
public async Task<ActionResult<Book>> GetBook(string Title)
{
var b = await _bookRepository.GetByName(Title); // Irar procurar na db qualquer livro que contem esse titulo sendo inteiro ou em pedaços
if(b == null)
return NotFound();

return Ok(b);
}

// Apenas o ADMIN pode usar para postar, atualizar e deletar, respeite o admin. https://youtu.be/yxq0ZnjEENs
[Authorize(Roles = "admin")]
[HttpPost]
public async Task<ActionResult<Book>> PostBook([FromBody] Book book)
{
var books = await _bookRepository.Get();
if(books == null)
return NoContent();

Book? new_book = new Book();
bool found = false;
foreach (Book b in books)
{
if(b.Title == null || book.Title == null)
continue;

if (b.Date == book.Date && b.Title.ToLower() == book.Title.ToLower())
{
found = true;
break;
}
}

if (found)
return NoContent();

new_book = await _bookRepository.Create(book);
if(new_book == null)
return NoContent();

return CreatedAtAction(nameof(GetBook), new { id = new_book.Id }, new_book);
}

[Authorize(Roles = "admin")]
[HttpDelete("{id}")]
public async Task<ActionResult?> Delete(int id)
{
Book? book = await _bookRepository.GetById(id);
if (book == null)
return NotFound();

await _bookRepository.Delete(id);

return NoContent();
}


[Authorize(Roles = "admin")]
[HttpPut("{id}")]
public async Task<ActionResult?> PutBooks(int id, [FromBody] Book book)
{
if (id != book.Id)
return NoContent();

await _bookRepository.Update(book);
return Ok(book);
}

// Qualquer anonimo pode autorizar
[AllowAnonymous]
[HttpPost("Auth")]
public ActionResult<dynamic> AuthUser([FromBody] User user)
{
string? token = _jwtAuthentication.Authenticate(user.Username, user.Password);
if (token == null)
return Unauthorized();
return Ok(new {
usuario = user.Username,
tokken = token
});
}
}

}
20 changes: 20 additions & 0 deletions APIBook/APIBook/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["APIBook/APIBook.csproj", "APIBook/"]
RUN dotnet restore "APIBook/APIBook.csproj"
COPY . .
WORKDIR "/src/APIBook"
RUN dotnet build "APIBook.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "APIBook.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "APIBook.dll"]
Loading