Skip to content

Commit

Permalink
Angular+C# end of sesstion 4
Browse files Browse the repository at this point in the history
  • Loading branch information
mdhayath64 committed Sep 9, 2023
1 parent 3c47443 commit 6aee83c
Show file tree
Hide file tree
Showing 25 changed files with 415 additions and 19 deletions.
35 changes: 35 additions & 0 deletions Angular/CSharp_Angular/DatingApp/.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/dotnet/vscode-csharp/blob/main/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}/API/bin/Debug/net7.0/API.dll",
"args": [],
"cwd": "${workspaceFolder}/API",
"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 Angular/CSharp_Angular/DatingApp/.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}/DatingApp.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/DatingApp.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/DatingApp.sln"
],
"problemMatcher": "$msCompile"
}
]
}
2 changes: 2 additions & 0 deletions Angular/CSharp_Angular/DatingApp/API/API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.9">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.9" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.32.3" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System.Security.Cryptography;
using System.Text;
using API.Data;
using API.DTOs;
using API.Entities;
using API.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace API.Controllers;

public class AccountController : BaseApiController
{
private readonly DataContext _context;
private readonly ITokenServices _tokenServices;

public AccountController(DataContext context, ITokenServices tokenServices)
{
_context = context;
_tokenServices = tokenServices;
}

[HttpPost("register")] // POST: api/account/register?username=dave&password=pwd
public async Task<ActionResult<UserDto>> Register(RegisterDto registerDto)
{
if (await UserExists(registerDto.UserName)) return BadRequest("User is taken");

using var hmac = new HMACSHA512(); //Hash-based message authentication code

var user = new AppUser
{
UserName = registerDto.UserName.ToLower(),
PasswordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(registerDto.Password)),
PasswordSalt = hmac.Key
};

_context.Users.Add(user);
await _context.SaveChangesAsync();

return new UserDto
{
UserName = user.UserName,
Token = _tokenServices.CreateToken(user)
};
}

[HttpPost("login")]
public async Task<ActionResult<UserDto>> Login(LoginDto loginDto)
{
var user = await _context.Users.SingleOrDefaultAsync(x =>
x.UserName == loginDto.UserName
);

if (user == null) return Unauthorized("Invalid username");

using var hmac = new HMACSHA512(user.PasswordSalt);

var computedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(loginDto.Password));

for (int i = 0; i < computedHash.Length; i++)
{
if (computedHash[i] != user.PasswordHash[i]) return Unauthorized("Invalid password!");
}

return new UserDto
{
UserName = user.UserName,
Token = _tokenServices.CreateToken(user)
};
}

private async Task<bool> UserExists(string userName)
{
return await _context.Users.AnyAsync(x => x.UserName == userName.ToLower());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Mvc;

namespace API.Controllers;

[ApiController]
[Route("api/[controller]")]
public class BaseApiController : ControllerBase
{

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using API.Data;
using API.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace API.Controllers;

[ApiController]
[Route("api/[controller]")] // /api/users
public class UsersController : ControllerBase
[Authorize]
public class UsersController : BaseApiController
{
private readonly DataContext _context;

Expand All @@ -16,6 +16,7 @@ public UsersController(DataContext context)
_context = context;
}

[AllowAnonymous]
[HttpGet]
public async Task<ActionResult<IEnumerable<AppUser>>> GetUsers()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

namespace API.Controllers;

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase

public class WeatherForecastController : BaseApiController
{
private static readonly string[] Summaries = new[]
{
Expand Down
11 changes: 11 additions & 0 deletions Angular/CSharp_Angular/DatingApp/API/DTOs/LoginDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;

namespace API.DTOs;

public class LoginDto
{
[Required]
public string UserName { get; set; }
[Required]
public string Password { get; set; }
}
11 changes: 11 additions & 0 deletions Angular/CSharp_Angular/DatingApp/API/DTOs/RegisterDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;

namespace API.DTOs;

public class RegisterDto
{
[Required]
public string UserName { get; set; }
[Required]
public string Password { get; set; }
}
7 changes: 7 additions & 0 deletions Angular/CSharp_Angular/DatingApp/API/DTOs/UserDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace API.DTOs;

public class UserDto
{
public string UserName { get; set; }
public string Token { get; set; }
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace API.Data.Migrations
{
/// <inheritdoc />
public partial class UserPasswordAdded : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<byte[]>(
name: "PasswordHash",
table: "Users",
type: "BLOB",
nullable: true);

migrationBuilder.AddColumn<byte[]>(
name: "PasswordSalt",
table: "Users",
type: "BLOB",
nullable: true);
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "PasswordHash",
table: "Users");

migrationBuilder.DropColumn(
name: "PasswordSalt",
table: "Users");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,18 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<byte[]>("PasswordHash")
.HasColumnType("BLOB");
b.Property<byte[]>("PasswordSalt")
.HasColumnType("BLOB");
b.Property<string>("UserName")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Users");
b.ToTable("Users", (string)null);
});
#pragma warning restore 612, 618
}
Expand Down
2 changes: 2 additions & 0 deletions Angular/CSharp_Angular/DatingApp/API/Entities/AppUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ public class AppUser
{
public int Id { get; set; }
public string UserName { get; set;}
public byte[] PasswordHash { get; set; }
public byte[] PasswordSalt { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using API.Data;
using API.Interfaces;
using API.Services;
using Microsoft.EntityFrameworkCore;

namespace API.Extensions;

public static class ApplicationServiceExtensions
{
public static IServiceCollection AddApplicationServices(this IServiceCollection services,
IConfiguration config)
{
services.AddDbContext<DataContext>(opt =>
{
opt.UseSqlite(config.GetConnectionString("DefaultConnection"));
});
services.AddCors();
services.AddScoped<ITokenServices, TokenService>();

return services;
}

}
Loading

0 comments on commit 6aee83c

Please sign in to comment.