Letieri
Letieri
CC#
Created by Letieri on 5/20/2024 in #help
How to Implement Automatic Versioning for NuGet Package Using GitHub Actions?
Hello everyone, I’m currently working on automating the release process for my NuGet package and would like to implement automatic versioning using GitHub Actions. I've managed to set up a workflow that builds and publishes the package to both GitHub Packages and NuGet.org, but I'm struggling to add the automatic version increment functionality. Here's my current workflow:
name: Publish to GitHub Packages

on:
push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Setup .NET Core SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0.x'

- name: Build solution
run: dotnet build Kayki.StringUtils.sln --configuration Release

- name: Run tests
run: dotnet test Kayki.StringUtilsTests/Kayki.StringUtilsTests.csproj --configuration Release

- name: Build package
run: |
cd Kayki.StringUtils
dotnet build -c Release -o out

- name: Publish to GitHub Packages
run: |
cd Kayki.StringUtils/out
dotnet nuget push *.nupkg --api-key ${{ secrets.PKG_TOKEN }} --source https://nuget.pkg.github.com/kaykiletieri/index.json --skip-duplicate


- name: Publish to NuGet.org
run: |
cd Kayki.StringUtils/out
dotnet nuget push *.nupkg --api-key ${{ secrets.PKG_NUGET_TOKEN }} --source https://api.nuget.org/v3/index.json --skip-duplicate
name: Publish to GitHub Packages

on:
push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Setup .NET Core SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0.x'

- name: Build solution
run: dotnet build Kayki.StringUtils.sln --configuration Release

- name: Run tests
run: dotnet test Kayki.StringUtilsTests/Kayki.StringUtilsTests.csproj --configuration Release

- name: Build package
run: |
cd Kayki.StringUtils
dotnet build -c Release -o out

- name: Publish to GitHub Packages
run: |
cd Kayki.StringUtils/out
dotnet nuget push *.nupkg --api-key ${{ secrets.PKG_TOKEN }} --source https://nuget.pkg.github.com/kaykiletieri/index.json --skip-duplicate


- name: Publish to NuGet.org
run: |
cd Kayki.StringUtils/out
dotnet nuget push *.nupkg --api-key ${{ secrets.PKG_NUGET_TOKEN }} --source https://api.nuget.org/v3/index.json --skip-duplicate
`
2 replies
CC#
Created by Letieri on 5/8/2024 in #help
Issue with unit test for Argon2-based password hash service
I'm encountering an issue with the implementation of a password hash service using the Argon2 algorithm. I've created a PasswordHasherService class that utilizes Argon2 to generate secure password hashes, along with a method to verify passwords. The implementation of the class seems to be correct, but I'm facing difficulties with a specific unit test. The unit test aims to verify if the VerifyPassword() method returns false when an incorrect salt is provided. Here's an overview of the problem: The PasswordHasherService class has three main methods: HashPassword(): generates a secure password hash using Argon2 and returns the hash along with the salt used. VerifyPassword(): checks if a provided password matches a provided password hash, taking into account the salt used during hash generation. GenerateSalt(): generates a random salt. The unit test in question, named VerifyPassword_ReturnsFalseForIncorrectSalt, checks if the VerifyPassword() method returns false when an incorrect salt is provided. However, even when intentionally providing an incorrect salt in the unit test, the returned result is true, indicating that the test is failing. I've reviewed the code multiple times and ensured that the implementation of the PasswordHasherService class is correct. I've also confirmed that the salt is being generated correctly using the GenerateSalt() method. However, I haven't been able to pinpoint the root cause of this issue. I'm reaching out to the community for assistance in understanding what might be causing this unexpected behavior and how I can fix my unit test to ensure it functions as expected. Any guidance or suggestions would be greatly appreciated. Thank you in advance for your help!
25 replies
CC#
Created by Letieri on 5/7/2024 in #help
Retrieving Roles with Empty Permission Arrays in Entity Framework Core Repository
public async Task<IEnumerable<Role>> GetAllWithPermissions()
{
return await _context.Roles
.AsNoTracking()
.Include(r => r.RolePermissions)
.ThenInclude(rp => rp.Permission)
.Where(r => r.DeletedAt == null
&& r.RolePermissions.Any(rp => rp.DeletedAt == null && rp.Permission != null
&& rp.Permission.DeletedAt == null))
.ToListAsync();
}
public async Task<IEnumerable<Role>> GetAllWithPermissions()
{
return await _context.Roles
.AsNoTracking()
.Include(r => r.RolePermissions)
.ThenInclude(rp => rp.Permission)
.Where(r => r.DeletedAt == null
&& r.RolePermissions.Any(rp => rp.DeletedAt == null && rp.Permission != null
&& rp.Permission.DeletedAt == null))
.ToListAsync();
}
When I use this repository it returns the records correctly, except for the records where the Permissions array is empty, it should also return these cases. When I use
All.()
All.()
instead of
Any.()
Any.()
it returns me those in which Permissions is empty but it does not return the roles in which I deleted any RolePermissions records.
6 replies
CC#
Created by Letieri on 4/30/2024 in #help
Many-to-many with class for join entity EF
I'm facing an issue with implementing soft deletes in a custom many-to-many relationship class. I've created a custom class to handle the relationship, but I'm struggling to figure out how to modify the repository's get method to only fetch entities where the relationship's DeletedAt is not null.
c#
public class Role : EntityBase
{
public required string Name { get; set; }
public string? Description { get; set; }
public ICollection<User> Users { get; set; } = [];
public ICollection<Permission> Permissions { get; set; } = [];
public ICollection<RolePermission> RolePermissions { get; set; } = [];
public ICollection<UserRole> UserRoles { get; set; } = [];
}
public class Permission : EntityBase
{
public required string Name { get; set; }
public string? Description { get; set; }
public ICollection<Role> Roles { get; set; } = [];
public ICollection<RolePermission> RolePermissions { get; set; } = [];
}

public class RolePermission : EntityBase
{

public required Guid RoleUuid { get; set; }
public Role? Role { get; set; }
public required Guid PermissionUuid { get; set; }
public Permission? Permission { get; set; }
}

public async Task<Role?> GetActiveWithPermissionByIdAsync(Guid uuid)
{
return await _context.Roles
.AsNoTracking()
.Include(r => r.Permissions.Where(p => p.DeletedAt == null))
.FirstOrDefaultAsync(r => r.Uuid == uuid && r.DeletedAt == null);
}
c#
public class Role : EntityBase
{
public required string Name { get; set; }
public string? Description { get; set; }
public ICollection<User> Users { get; set; } = [];
public ICollection<Permission> Permissions { get; set; } = [];
public ICollection<RolePermission> RolePermissions { get; set; } = [];
public ICollection<UserRole> UserRoles { get; set; } = [];
}
public class Permission : EntityBase
{
public required string Name { get; set; }
public string? Description { get; set; }
public ICollection<Role> Roles { get; set; } = [];
public ICollection<RolePermission> RolePermissions { get; set; } = [];
}

public class RolePermission : EntityBase
{

public required Guid RoleUuid { get; set; }
public Role? Role { get; set; }
public required Guid PermissionUuid { get; set; }
public Permission? Permission { get; set; }
}

public async Task<Role?> GetActiveWithPermissionByIdAsync(Guid uuid)
{
return await _context.Roles
.AsNoTracking()
.Include(r => r.Permissions.Where(p => p.DeletedAt == null))
.FirstOrDefaultAsync(r => r.Uuid == uuid && r.DeletedAt == null);
}
20 replies
CC#
Created by Letieri on 4/25/2024 in #help
✅ Many-to-many relationship using Entity Framework
Can I implement a many-to-many relationship using Entity Framework but using a custom intermediary entity? If so, how?
2 replies
CC#
Created by Letieri on 4/23/2024 in #help
Argon2
My hash verification method is wrong, can anyone tell me how I can fix it?
c#
using Konscious.Security.Cryptography;
using RegulatorioAuth.Application.Services.Interfaces;
using System.Security.Cryptography;
using System.Text;

public class PasswordHasherService : IPasswordHasherService
{
public (string HashedPassword, byte[] Salt) HashPassword(string password)
{
var salt = GenerateSalt();

var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password))
{
Salt = salt,
DegreeOfParallelism = 8,
MemorySize = 65536,
Iterations = 4
};

byte[] hash = argon2.GetBytes(16);
string hashedPassword = Convert.ToBase64String(hash);


return (hashedPassword, salt);
}

public bool VerifyPassword(string password, string hashedPassword, byte[] salt)
{
byte[] hashToVerify = Convert.FromBase64String(hashedPassword);

var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password))
{
Salt = salt,
DegreeOfParallelism = 8,
MemorySize = 65536,
Iterations = 4
};

return argon2.Equals(hashToVerify);
}

private static byte[] GenerateSalt()
{
byte[] salt = new byte[16];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
return salt;
}
}
c#
using Konscious.Security.Cryptography;
using RegulatorioAuth.Application.Services.Interfaces;
using System.Security.Cryptography;
using System.Text;

public class PasswordHasherService : IPasswordHasherService
{
public (string HashedPassword, byte[] Salt) HashPassword(string password)
{
var salt = GenerateSalt();

var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password))
{
Salt = salt,
DegreeOfParallelism = 8,
MemorySize = 65536,
Iterations = 4
};

byte[] hash = argon2.GetBytes(16);
string hashedPassword = Convert.ToBase64String(hash);


return (hashedPassword, salt);
}

public bool VerifyPassword(string password, string hashedPassword, byte[] salt)
{
byte[] hashToVerify = Convert.FromBase64String(hashedPassword);

var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password))
{
Salt = salt,
DegreeOfParallelism = 8,
MemorySize = 65536,
Iterations = 4
};

return argon2.Equals(hashToVerify);
}

private static byte[] GenerateSalt()
{
byte[] salt = new byte[16];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
return salt;
}
}
11 replies