Skip to content

Commit b2993d3

Browse files
committed
Added login (not tested)
1 parent ad1d067 commit b2993d3

File tree

4 files changed

+108
-53
lines changed

4 files changed

+108
-53
lines changed

API.cs

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212

1313
namespace MODSI_SQLRestAPI
1414
{
15-
public class Points
15+
public class API
1616
{
1717
private readonly ILogger _logger;
1818
private readonly DatabaseHandler _databaseHandler;
1919

20-
public Points(ILoggerFactory loggerFactory)
20+
public API(ILoggerFactory loggerFactory)
2121
{
22-
_logger = loggerFactory.CreateLogger<Points>();
22+
_logger = loggerFactory.CreateLogger<API>();
2323
_databaseHandler = new DatabaseHandler();
2424
}
2525

@@ -382,18 +382,22 @@ public async Task<HttpResponseData> AddUser([HttpTrigger(AuthorizationLevel.Func
382382
var requestBody = await new StreamReader(req.Body).ReadToEndAsync();
383383
var user = JsonSerializer.Deserialize<User>(requestBody);
384384

385+
// Generate salt and hash password
386+
var salt = PasswordUtils.GenerateSalt();
387+
var passwordHash = PasswordUtils.HashPassword(user.Password, salt);
388+
385389
// Map MODSI_SQLRestAPI.User to MODSI_SQLRestAPI.DatabaseHandler.User
386-
var dbUser = new DatabaseHandler.User
390+
var dbUser = new User
387391
{
388-
ID = user.ID,
389392
Name = user.Name,
390393
Email = user.Email,
391-
Password = user.Password,
394+
Password = passwordHash,
392395
Username = user.Username,
393-
Role = user.Role,
394-
CreatedAt = user.CreatedAt,
395-
IsActive = user.IsActive,
396-
Group = user.Group
396+
Role = "User",
397+
CreatedAt = DateTime.UtcNow,
398+
IsActive = true,
399+
Group = "USER",
400+
Salt = salt
397401
};
398402

399403
await _databaseHandler.AddUserAsync(dbUser);
@@ -410,7 +414,6 @@ public async Task<HttpResponseData> AddUser([HttpTrigger(AuthorizationLevel.Func
410414
}
411415
}
412416

413-
414417
[Function("DeleteUserById")]
415418
public async Task<HttpResponseData> DeleteUserById([HttpTrigger(AuthorizationLevel.Function, "delete", Route = "User/Delete/{id:int}")] HttpRequestData req, int id)
416419
{
@@ -441,7 +444,7 @@ public async Task<HttpResponseData> UpdateUserById([HttpTrigger(AuthorizationLev
441444
user.ID = id;
442445

443446
// Map MODSI_SQLRestAPI.User to MODSI_SQLRestAPI.DatabaseHandler.User
444-
var dbUser = new DatabaseHandler.User
447+
var dbUser = new User
445448
{
446449
ID = user.ID,
447450
Name = user.Name,
@@ -468,15 +471,13 @@ public async Task<HttpResponseData> UpdateUserById([HttpTrigger(AuthorizationLev
468471
}
469472
}
470473

471-
472474
[Function("EmailUserExists")]
473-
474475
public async Task<HttpResponseData> EmailUserExists(
475476
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "User/EmailExists")] HttpRequestData req)
476477
{
477478
try
478479
{
479-
// Obter o email do parâmetro de consulta
480+
// Extract email from query string
480481
string email = req.Query["email"];
481482

482483
if (string.IsNullOrEmpty(email))
@@ -498,14 +499,13 @@ public async Task<HttpResponseData> EmailUserExists(
498499
}
499500
}
500501

501-
502502
[Function("GetUserByEmail")]
503503
public async Task<HttpResponseData> GetUserByEmail(
504-
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "User/GetByEmail")] HttpRequestData req)
504+
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "User/GetByEmail")] HttpRequestData req)
505505
{
506506
try
507507
{
508-
// Extrai o email da query string
508+
// Extract email from query string
509509
string email = req.Query["email"];
510510

511511
if (string.IsNullOrEmpty(email))
@@ -535,6 +535,24 @@ public async Task<HttpResponseData> GetUserByEmail(
535535

536536
#endregion
537537

538+
}
539+
internal static class PasswordUtils
540+
{
541+
public static string GenerateSalt()
542+
{
543+
// Generate a cryptographic random salt
544+
return Convert.ToBase64String(Guid.NewGuid().ToByteArray());
545+
}
538546

547+
public static string HashPassword(string password, string salt)
548+
{
549+
// Combine password and salt, then hash using SHA256
550+
using (var sha256 = System.Security.Cryptography.SHA256.Create())
551+
{
552+
var combined = System.Text.Encoding.UTF8.GetBytes(password + salt);
553+
var hash = sha256.ComputeHash(combined);
554+
return Convert.ToBase64String(hash);
555+
}
556+
}
539557
}
540558
}

DataFormats.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,8 @@ public class User
2727
public string Role { get; set; }
2828
public DateTime CreatedAt { get; set; }
2929
public bool IsActive { get; set; }
30-
3130
public string Group { get; set; }
32-
31+
public string Salt { get; set; }
3332
}
3433

3534
}

DatabaseHandler.cs

Lines changed: 70 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Collections.Generic;
33
using System.Configuration;
44
using System.Data.SqlClient;
5+
using System.Security.Cryptography;
6+
using System.Text;
57
using System.Threading.Tasks;
68

79
namespace MODSI_SQLRestAPI
@@ -253,18 +255,6 @@ public async Task SetRandomPieChartsAsync()
253255
#endregion
254256

255257
#region User Management
256-
public class User
257-
{
258-
public int ID { get; set; }
259-
public string Name { get; set; }
260-
public string Email { get; set; }
261-
public string Password { get; set; }
262-
public string Username { get; set; }
263-
public string Role { get; set; }
264-
public DateTime CreatedAt { get; set; }
265-
public bool IsActive { get; set; }
266-
public string Group { get; set; } // Nova propriedade
267-
}
268258

269259
public async Task<List<User>> GetAllUsersAsync()
270260
{
@@ -289,7 +279,7 @@ public async Task<List<User>> GetAllUsersAsync()
289279
Role = reader.GetString(5),
290280
CreatedAt = reader.GetDateTime(6),
291281
IsActive = reader.GetBoolean(7),
292-
Group = reader.GetString(8) // Nova coluna
282+
Group = reader.GetString(8)
293283
});
294284
}
295285
}
@@ -298,31 +288,68 @@ public async Task<List<User>> GetAllUsersAsync()
298288
return users;
299289
}
300290

301-
// Métodos atualizados para incluir o Group:
302-
303291
public async Task AddUserAsync(User user)
304292
{
293+
var salt = PasswordUtils.GenerateSalt();
294+
var passwordHash = PasswordUtils.HashPassword(user.Password, salt);
295+
305296
using (SqlConnection conn = new SqlConnection(_connectionString))
306297
{
307298
await conn.OpenAsync();
308-
var query = $"INSERT INTO {_user_DB} (Name, Email, Password, Username, Role, CreatedAt, IsActive, [Group]) " +
309-
"VALUES (@Name, @Email, @Password, @Username, @Role, @CreatedAt, @IsActive, @Group)";
299+
var query = $"INSERT INTO {_user_DB} (Name, Email, Password, Username, Role, CreatedAt, IsActive, [Group], Salt) " +
300+
"VALUES (@Name, @Email, @Password, @Username, @Role, @CreatedAt, @IsActive, @Group, @Salt)";
310301
using (SqlCommand cmd = new SqlCommand(query, conn))
311302
{
312303
cmd.Parameters.AddWithValue("@Name", user.Name);
313304
cmd.Parameters.AddWithValue("@Email", user.Email);
314-
cmd.Parameters.AddWithValue("@Password", user.Password);
305+
cmd.Parameters.AddWithValue("@Password", passwordHash);
315306
cmd.Parameters.AddWithValue("@Username", user.Username);
316307
cmd.Parameters.AddWithValue("@Role", user.Role);
317308
cmd.Parameters.AddWithValue("@CreatedAt", user.CreatedAt);
318309
cmd.Parameters.AddWithValue("@IsActive", user.IsActive);
319-
cmd.Parameters.AddWithValue("@Group", user.Group); // Novo parâmetro
310+
cmd.Parameters.AddWithValue("@Group", user.Group);
311+
cmd.Parameters.AddWithValue("@Salt", salt);
320312
await cmd.ExecuteNonQueryAsync();
321313
}
322314
}
323315
}
324316

317+
public async Task<User> AuthenticateUserAsync(string username, string password)
318+
{
319+
using (SqlConnection conn = new SqlConnection(_connectionString))
320+
{
321+
await conn.OpenAsync();
322+
var query = $"SELECT ID, Name, Email, Password, Username, Role, CreatedAt, IsActive, [Group], Salt FROM {_user_DB} WHERE Username = @Username";
323+
using (SqlCommand cmd = new SqlCommand(query, conn))
324+
{
325+
cmd.Parameters.AddWithValue("@Username", username);
326+
using (SqlDataReader reader = await cmd.ExecuteReaderAsync())
327+
{
328+
if (await reader.ReadAsync())
329+
{
330+
var storedHash = reader.GetString(2);
331+
var salt = reader.GetString(9);
325332

333+
if (storedHash == PasswordUtils.HashPassword(password, salt))
334+
{
335+
return new User
336+
{
337+
ID = reader.GetInt32(0),
338+
Name = reader.GetString(1),
339+
Email = reader.GetString(2),
340+
Username = reader.GetString(3),
341+
Role = reader.GetString(4),
342+
CreatedAt = reader.GetDateTime(5),
343+
IsActive = reader.GetBoolean(6),
344+
Group = reader.GetString(7)
345+
};
346+
}
347+
}
348+
}
349+
}
350+
}
351+
return null;
352+
}
326353

327354
public async Task UpdateUserByIdAsync(User user)
328355
{
@@ -340,13 +367,12 @@ public async Task UpdateUserByIdAsync(User user)
340367
cmd.Parameters.AddWithValue("@Role", user.Role);
341368
cmd.Parameters.AddWithValue("@CreatedAt", user.CreatedAt);
342369
cmd.Parameters.AddWithValue("@IsActive", user.IsActive);
343-
cmd.Parameters.AddWithValue("@Group", user.Group); // Novo parâmetro
370+
cmd.Parameters.AddWithValue("@Group", user.Group);
344371
await cmd.ExecuteNonQueryAsync();
345372
}
346373
}
347374
}
348375

349-
350376
public async Task<bool> EmailUserExistsAsync(string email)
351377
{
352378
using (SqlConnection conn = new SqlConnection(_connectionString))
@@ -362,10 +388,6 @@ public async Task<bool> EmailUserExistsAsync(string email)
362388
}
363389
}
364390

365-
// Get use by email
366-
367-
//GetUserByEmailAsync
368-
369391
public async Task<User> GetUserByEmailAsync(string email)
370392
{
371393
User user = null;
@@ -390,7 +412,7 @@ public async Task<User> GetUserByEmailAsync(string email)
390412
Role = reader.GetString(5),
391413
CreatedAt = reader.GetDateTime(6),
392414
IsActive = reader.GetBoolean(7),
393-
Group = reader.GetString(8) // Nova coluna
415+
Group = reader.GetString(8)
394416
};
395417
}
396418
}
@@ -399,9 +421,6 @@ public async Task<User> GetUserByEmailAsync(string email)
399421
return user;
400422
}
401423

402-
//DeleteUserByIdAsync
403-
404-
405424
public async Task DeleteUserByIdAsync(int id)
406425
{
407426
using (SqlConnection conn = new SqlConnection(_connectionString))
@@ -416,8 +435,6 @@ public async Task DeleteUserByIdAsync(int id)
416435
}
417436
}
418437

419-
//GetUserByIdAsync
420-
421438
public async Task<User> GetUserByIdAsync(int id)
422439
{
423440
User user = null;
@@ -442,7 +459,7 @@ public async Task<User> GetUserByIdAsync(int id)
442459
Role = reader.GetString(5),
443460
CreatedAt = reader.GetDateTime(6),
444461
IsActive = reader.GetBoolean(7),
445-
Group = reader.GetString(8) // Nova coluna
462+
Group = reader.GetString(8)
446463
};
447464
}
448465
}
@@ -451,7 +468,28 @@ public async Task<User> GetUserByIdAsync(int id)
451468
return user;
452469
}
453470

471+
public static class PasswordUtils
472+
{
473+
public static string HashPassword(string password, string salt)
474+
{
475+
using (var sha256 = SHA256.Create())
476+
{
477+
var combined = Encoding.UTF8.GetBytes(password + salt);
478+
var hash = sha256.ComputeHash(combined);
479+
return Convert.ToBase64String(hash);
480+
}
481+
}
454482

483+
public static string GenerateSalt()
484+
{
485+
var saltBytes = new byte[16];
486+
using (var rng = RandomNumberGenerator.Create())
487+
{
488+
rng.GetBytes(saltBytes);
489+
}
490+
return Convert.ToBase64String(saltBytes);
491+
}
492+
}
455493
#endregion
456494

457495
}

MODSI-SQLRestAPI.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 17
4-
VisualStudioVersion = 17.13.35919.96 d17.13
4+
VisualStudioVersion = 17.13.35919.96
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MODSI-SQLRestAPI", "MODSI-SQLRestAPI.csproj", "{2845EF61-B4C1-48F0-8779-E8ACFB21F27C}"
77
EndProject

0 commit comments

Comments
 (0)