Skip to content

Commit

Permalink
Merge pull request #48 from thiagoloureiro/development
Browse files Browse the repository at this point in the history
Improvements for MonitorGroups
  • Loading branch information
thiagoloureiro committed May 14, 2024
2 parents 7fec193 + 48d4cbb commit 25d051b
Show file tree
Hide file tree
Showing 17 changed files with 120 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.5.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.5.2" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.2" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ public async Task Create(UserCreation userCreation)

public async Task CreateFromAzure(UserCreationFromAzure userCreation)
{
var userList = await _userRepository.GetAll();
if (userList != null && !userList.Any())
{
userCreation.IsAdmin = true;
}

await _userRepository.CreateFromAzure(userCreation);
}

Expand Down Expand Up @@ -60,6 +66,7 @@ public async Task ResetPassword(string username)
{
return await _userRepository.GetByUsername(username);
}

public Task<IEnumerable<UserDto>?> GetAll()
{
return _userRepository.GetAll();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ public class UserCreationFromAzure(string username, string email)
public Guid Id { get; set; } = Guid.NewGuid();
public string Username { get; set; } = username;
public string Email { get; set; } = email;
public bool IsAdmin { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,37 @@ public UserRepository(IConfiguration configuration, IMapper mapper) : base(confi

public async Task<UserDto?> Get(Guid id)
{
const string sql = "SELECT Id, Email, Username, IsAdmin, CreatedAt, UpdatedAt, LastLogon FROM Users WHERE Id = @Id";
const string sql =
"SELECT Id, Email, Username, IsAdmin, CreatedAt, UpdatedAt, LastLogon FROM Users WHERE Id = @Id";
var user = await ExecuteQueryFirstOrDefaultAsync<User>(sql, new { Id = id });
return _mapper.Map<UserDto>(user);
}

public async Task<UserDto?> GetByEmail(string email)
{
const string sql = "SELECT Id, Email, Username, IsAdmin, CreatedAt, UpdatedAt, LastLogon FROM Users WHERE LOWER(Email) = LOWER(@Email)";
var user = await ExecuteQueryFirstOrDefaultAsync<User>(sql, new { Email = email.ToLower(CultureInfo.InvariantCulture) });
const string sql =
"SELECT Id, Email, Username, IsAdmin, CreatedAt, UpdatedAt, LastLogon FROM Users WHERE LOWER(Email) = LOWER(@Email)";
var user = await ExecuteQueryFirstOrDefaultAsync<User>(sql,
new { Email = email.ToLower(CultureInfo.InvariantCulture) });
return _mapper.Map<UserDto>(user);
}

public async Task<UserDto?> GetByUsername(string username)
{
const string sql = "SELECT Id, Email, Username, IsAdmin, CreatedAt, UpdatedAt, LastLogon FROM Users WHERE LOWER(Username) = LOWER(@Username)";
var user = await ExecuteQueryFirstOrDefaultAsync<User>(sql, new { Username = username.ToLower(CultureInfo.InvariantCulture) });
const string sql =
"SELECT Id, Email, Username, IsAdmin, CreatedAt, UpdatedAt, LastLogon FROM Users WHERE LOWER(Username) = LOWER(@Username)";
var user = await ExecuteQueryFirstOrDefaultAsync<User>(sql,
new { Username = username.ToLower(CultureInfo.InvariantCulture) });
return _mapper.Map<UserDto>(user);
}

public async Task<IEnumerable<UserDto>?> GetAll()
{
const string sql = "SELECT Id, Email, Username, IsAdmin, CreatedAt, UpdatedAt, LastLogon FROM Users";
var user = await ExecuteQueryAsync<User>(sql);
return _mapper.Map<List<UserDto>?>(user);
}

public async Task Create(UserCreation userCreation)
{
string checkExistingUserSql = "SELECT Id FROM Users WHERE LOWER(Email) = @Email";
Expand All @@ -56,6 +63,7 @@ public async Task Create(UserCreation userCreation)
{
throw new InvalidOperationException("The email is already registered, please choose another.");
}

checkExistingUserSql = "SELECT Id FROM Users WHERE LOWER(Username) = @Username";
existingUser = await ExecuteQueryFirstOrDefaultAsync<Guid?>(checkExistingUserSql, new
{
Expand All @@ -65,6 +73,7 @@ public async Task Create(UserCreation userCreation)
{
throw new InvalidOperationException("The username is already registered, please choose another.");
}

var salt = PasswordHasher.GenerateSalt();
var hashedPassword = PasswordHasher.HashPassword(userCreation.Password, salt);

Expand All @@ -80,20 +89,21 @@ INSERT INTO Users (Id, Username, Email, Password, Salt, IsAdmin, CreatedAt)
Salt = salt,
userCreation.IsAdmin,
CreatedAt = DateTime.UtcNow

});
}

public async Task CreateFromAzure(UserCreationFromAzure userCreation)
{
const string insertUserSql = @"
INSERT INTO Users (Id, Username, Email, IsAdmin, CreatedAt)
VALUES (NEWID(), @Username, @Email, 0, @CreatedAt)";
INSERT INTO Users (Id, Username, Email, IsAdmin, CreatedAt)
VALUES (NEWID(), @Username, @Email, @IsAdmin, @CreatedAt)";

await ExecuteNonQueryAsync(insertUserSql, new
{
userCreation.Username,
Email = userCreation.Email.ToLower(CultureInfo.InvariantCulture),
CreatedAt = DateTime.UtcNow
CreatedAt = DateTime.UtcNow,
userCreation.IsAdmin
});
}

Expand Down Expand Up @@ -127,11 +137,13 @@ FROM Users
{
throw new InvalidOperationException("Email already exists.");
}

if (updateEmail)
{
conditions.Add("LOWER(Email) = LOWER(@Email)");
parameters.Add("Email", userUpdate.Email?.ToLower(CultureInfo.InvariantCulture));
}

existingUser = await ExecuteQueryFirstOrDefaultAsync<Guid?>(checkUserSql, parameters);
if (existingUser.HasValue)
{
Expand Down Expand Up @@ -170,7 +182,8 @@ public async Task<string> ResetPassword(string username)
var salt = PasswordHasher.GenerateSalt();
var hashedPassword = PasswordHasher.HashPassword(newPassword, salt);

const string insertUserSql = @"UPDATE User SET Password = @Password, Salt = @Salt, UpdatedAt = @UpdatedAt WHERE LOWER(Username) = LOWER(@Username)";
const string insertUserSql =
@"UPDATE User SET Password = @Password, Salt = @Salt, UpdatedAt = @UpdatedAt WHERE LOWER(Username) = LOWER(@Username)";

await ExecuteNonQueryAsync(insertUserSql, new
{
Expand All @@ -184,8 +197,10 @@ public async Task<string> ResetPassword(string username)

public async Task<UserDto?> Login(string username, string password)
{
const string sql = "SELECT Id, Email, Username, IsAdmin, Password, Salt, CreatedAt, UpdatedAt, LastLogon FROM Users WHERE LOWER(Username) = LOWER(@username)";
var user = await ExecuteQueryFirstOrDefaultAsync<User>(sql, new { username = username.ToLower(CultureInfo.InvariantCulture) });
const string sql =
"SELECT Id, Email, Username, IsAdmin, Password, Salt, CreatedAt, UpdatedAt, LastLogon FROM Users WHERE LOWER(Username) = LOWER(@username)";
var user = await ExecuteQueryFirstOrDefaultAsync<User>(sql,
new { username = username.ToLower(CultureInfo.InvariantCulture) });

if (user is null || !PasswordHasher.VerifyPassword(password, user.Password, user.Salt))
{
Expand All @@ -194,4 +209,4 @@ public async Task<string> ResetPassword(string username)

return _mapper.Map<UserDto>(user);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" />
<PackageReference Include="Microsoft.Identity.Web" Version="2.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
<PackageReference Include="Sentry.AspNetCore" Version="4.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
<PackageReference Include="Sentry.AspNetCore" Version="4.6.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.1" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.6.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,21 @@ public async Task<IEnumerable<MonitorGroup>> GetMonitorGroupList(string jwtToken

monitorGroupList = monitorGroupList.Where(x => ids.Contains(x.Id)).ToList();

return monitorGroupList;
}

public async Task<IEnumerable<MonitorGroup>> GetMonitorDashboardGroupListByUser(string jwtToken)
{
var ids = await GetUserGroupMonitorListIds(jwtToken);
var monitorGroupList = await _monitorGroupRepository.GetMonitorGroupList();

if (ids == null || !ids.Any())
{
return new List<MonitorGroup> { new MonitorGroup { Id = 0, Name = "No Groups Found" } };
}

monitorGroupList = monitorGroupList.Where(x => ids.Contains(x.Id)).ToList();

var allMonitorIds = monitorGroupList
.SelectMany(group => group.Monitors?.Select(m => m.Id) ?? Enumerable.Empty<int>()).ToList();
var allDashboardData = await GetMonitorDashboardDataList(allMonitorIds);
Expand Down Expand Up @@ -173,6 +188,11 @@ public async Task<IEnumerable<MonitorGroup>> GetMonitorGroupList(string jwtToken
return monitorGroupList;
}

public async Task<MonitorGroup?> GetMonitorGroupByName(string monitorGroupName)
{
return await _monitorGroupRepository.GetMonitorGroupByName(monitorGroupName);
}

public async Task<MonitorGroup> GetMonitorGroupById(int id)
{
return await _monitorGroupRepository.GetMonitorGroupById(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ public interface IMonitorGroupRepository
Task AddMonitorGroup(MonitorGroup monitorGroup);
Task UpdateMonitorGroup(MonitorGroup monitorGroup);
Task DeleteMonitorGroup(int id);
Task<MonitorGroup?> GetMonitorGroupByName(string monitorGroupName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ public interface IMonitorGroupService
Task DeleteMonitorGroup(string jwtToken, int id);
Task<List<int>?> GetUserGroupMonitorListIds(string token);
Task<IEnumerable<MonitorGroup>> GetMonitorGroupList();
Task<IEnumerable<MonitorGroup>> GetMonitorDashboardGroupListByUser(string jwtToken);
Task<MonitorGroup?> GetMonitorGroupByName(string monitorGroupName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.11.3" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.20.0" />
<PackageReference Include="CustomLog.Client" Version="1.0.4" />
<PackageReference Include="Dapper" Version="2.1.44" />
<PackageReference Include="EasyMemoryCache" Version="2.0.3" />
<PackageReference Include="EPPlus" Version="7.1.2" />
<PackageReference Include="Hangfire.Core" Version="1.8.12" />
<PackageReference Include="MassTransit.Abstractions" Version="8.2.2" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Polly" Version="8.3.1" />
<PackageReference Include="Polly" Version="8.4.0" />
<PackageReference Include="Selenium.WebDriver" Version="4.20.0" />
<PackageReference Include="Sentry" Version="4.5.0" />
<PackageReference Include="Sentry" Version="4.6.1" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,11 @@ public async Task DeleteMonitorGroup(int id)
string sqlDeleteGroup = @"DELETE FROM [MonitorGroup] WHERE id = @id";
await db.QueryAsync<MonitorGroup>(sqlDeleteGroup, new { id }, commandType: CommandType.Text);
}

public async Task<MonitorGroup?> GetMonitorGroupByName(string monitorGroupName)
{
await using var db = new SqlConnection(_connstring);
string sql = @"SELECT Id, Name FROM [MonitorGroup] WHERE Name=@monitorGroupName";
return await db.QueryFirstOrDefaultAsync<MonitorGroup>(sql, new { monitorGroupName }, commandType: CommandType.Text);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="NSubstitute" Version="5.1.0" />
<PackageReference Include="xunit" Version="2.8.0" />
<PackageReference Include="Xunit.DependencyInjection" Version="9.2.1" />
<PackageReference Include="Xunit.DependencyInjection" Version="9.3.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
<PackageReference Include="Microsoft.Identity.Web" Version="2.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Sentry" Version="4.5.0" />
<PackageReference Include="Sentry.AspNetCore" Version="4.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.5.0" />
<PackageReference Include="Sentry" Version="4.6.1" />
<PackageReference Include="Sentry.AspNetCore" Version="4.6.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.1" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.6.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.6.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public async Task<IActionResult> GetMonitorGroupList()
}

[SwaggerOperation(Summary =
"Retrieves a List of all Monitor Groups (including monitor list + dashboard data) By User Token")]
"Retrieves a List of all Monitor Groups By User Token")]
[ProducesResponseType(typeof(IEnumerable<MonitorGroup>), StatusCodes.Status200OK)]
[HttpGet("monitorGroupListByUser")]
[Authorize]
Expand All @@ -45,13 +45,30 @@ public async Task<IActionResult> GetMonitorGroupListByUser()
var result = await _monitorGroupService.GetMonitorGroupList(jwtToken);
return Ok(result);
}

[SwaggerOperation(Summary =
"Retrieves a List of all Monitor Groups (including monitor list + dashboard data) By User Token")]
[ProducesResponseType(typeof(IEnumerable<MonitorGroup>), StatusCodes.Status200OK)]
[HttpGet("monitorGroupListByUser/{environment}")]
[HttpGet("monitorDashboardGroupListByUser")]
[Authorize]
public async Task<IActionResult> GetMonitorGroupListByEnvironment(
public async Task<IActionResult> GetMonitorDashboardGroupListByUser()
{
var jwtToken = TokenUtils.GetJwtToken(Request.Headers["Authorization"].ToString());
if (jwtToken == null)
{
return BadRequest("Invalid Token");
}

var result = await _monitorGroupService.GetMonitorDashboardGroupListByUser(jwtToken);
return Ok(result);
}

[SwaggerOperation(Summary =
"Retrieves a List of all Monitor Groups (including monitor list + dashboard data) By User Token and Environment")]
[ProducesResponseType(typeof(IEnumerable<MonitorGroup>), StatusCodes.Status200OK)]
[HttpGet("monitorDashboardGroupListByUser/{environment}")]
[Authorize]
public async Task<IActionResult> GetMonitorDashboardGroupListByUser(
MonitorEnvironment environment = MonitorEnvironment.Production)
{
var jwtToken = TokenUtils.GetJwtToken(Request.Headers["Authorization"].ToString());
Expand Down Expand Up @@ -87,6 +104,12 @@ public async Task<IActionResult> AddMonitorToGroup([FromBody] MonitorGroupItems
[HttpPost("addMonitorGroup")]
public async Task<IActionResult> AddMonitorGroup([FromBody] MonitorGroup monitorGroup)
{
var monitor = await _monitorGroupService.GetMonitorGroupByName(monitorGroup.Name);
if(monitor?.Id != 0)
{
return BadRequest("Monitor Already Exists");
}

await _monitorGroupService.AddMonitorGroup(monitorGroup);
return Ok();
}
Expand All @@ -96,6 +119,12 @@ public async Task<IActionResult> AddMonitorGroup([FromBody] MonitorGroup monitor
[HttpPost("updateMonitorGroup")]
public async Task<IActionResult> UpdateMonitorGroup([FromBody] MonitorGroup monitorGroup)
{
var monitor = await _monitorGroupService.GetMonitorGroupByName(monitorGroup.Name);
if(monitor?.Id != 0)
{
return BadRequest("Monitor Already Exists");
}

await _monitorGroupService.UpdateMonitorGroup(monitorGroup);
return Ok();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<ItemGroup>
<PackageReference Include="AlertHawk.Authentication.Domain" Version="1.0.3" />
<PackageReference Include="Sentry" Version="4.5.0" />
<PackageReference Include="Sentry" Version="4.6.1" />
<PackageReference Include="Telegram.Bot" Version="19.0.0" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<PackageReference Include="Dapper" Version="2.1.44" />
<PackageReference Include="MassTransit.Abstractions" Version="8.2.2" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Polly" Version="8.3.1" />
<PackageReference Include="Sentry" Version="4.5.0" />
<PackageReference Include="Polly" Version="8.4.0" />
<PackageReference Include="Sentry" Version="4.6.1" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<PackageReference Include="NSubstitute" Version="5.1.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="xunit" Version="2.8.0" />
<PackageReference Include="Xunit.DependencyInjection" Version="9.2.1" />
<PackageReference Include="Xunit.DependencyInjection" Version="9.3.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand Down
Loading

0 comments on commit 25d051b

Please sign in to comment.