Skip to content

Commit

Permalink
Merge pull request #25 from Star-Academy/role-authorization
Browse files Browse the repository at this point in the history
Role authorization
  • Loading branch information
Ftm-Sayadzadeh authored Aug 27, 2024
2 parents 44d7cd2 + 3636319 commit c9d9105
Show file tree
Hide file tree
Showing 44 changed files with 905 additions and 266 deletions.
16 changes: 9 additions & 7 deletions mohaymen-codestar-Team02/Controllers/AdminController.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using mohaymen_codestar_Team02.Dto.Role;
using mohaymen_codestar_Team02.Dto.User;
Expand All @@ -9,6 +10,7 @@
namespace mohaymen_codestar_Team02.Controllers;

[ApiController]
[Authorize(Roles = nameof(RoleType.SystemAdmin))]
[Route("[controller]")]
public class AdminController : ControllerBase
{
Expand Down Expand Up @@ -53,11 +55,11 @@ public async Task<IActionResult> Register([FromBody] RegisterUserDto request)
}

[HttpDelete("users/{username}")]
public async Task<IActionResult> Delete([FromBody] DeleteUserDto request)
public async Task<IActionResult> Delete(string username)
{
var user = new User
{
Username = request.Username
Username = username
};

ServiceResponse<GetUserDto?> response =
Expand All @@ -75,23 +77,23 @@ public async Task<IActionResult> GetAllRoles()
}

[HttpPut("users/{username}/roles")]
public async Task<IActionResult> AddRole([FromBody] AddUserRoleDto request)
public async Task<IActionResult> AddRole([FromBody] AddUserRoleDto request, string username)
{
ServiceResponse<GetUserDto?> response =
await _adminService.AddRole(
new User { Username = request.Username },
new User { Username = username },
new Role() { RoleType = request.RoleType }
);

return StatusCode((int)response.Type, response);
}

[HttpDelete("users/{username}/roles/{roleType}")]
public async Task<IActionResult> DeleteRole([FromBody] DeleteUserRoleDto request)
[HttpDelete("users/{username}/roles")]
public async Task<IActionResult> DeleteRole([FromBody] DeleteUserRoleDto request, string username)
{
ServiceResponse<GetUserDto?> response =
await _adminService.DeleteRole(
new User { Username = request.Username },
new User { Username = username },
new Role() { RoleType = request.RoleType }
);

Expand Down
19 changes: 17 additions & 2 deletions mohaymen-codestar-Team02/Controllers/AuthenticationController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using mohaymen_codestar_Team02.Dto.Permission;
using mohaymen_codestar_Team02.Dto.User;
using mohaymen_codestar_Team02.Dto.UserDtos;
using mohaymen_codestar_Team02.Models;
Expand All @@ -20,15 +21,29 @@ public AuthenticationController(IAuthenticationService authenticationService)
[HttpPost("login")]
public async Task<IActionResult> Login(LoginUserDto request)
{
ServiceResponse<GetUserDto?> response = await _authenticationService.Login(request.Username, request.Password);
var response = await _authenticationService.Login(request.Username, request.Password);
return StatusCode((int)response.Type, response);
}

[HttpPost("logout")]
//[ValidateAntiForgeryToken]
public IActionResult Logout()
{
ServiceResponse<string?> response = _authenticationService.Logout();
var response = _authenticationService.Logout();
return StatusCode((int)response.Type, response);
}

[HttpGet("permission")]
public async Task<IActionResult> GetPermission()
{
var response = await _authenticationService.GetPermission();
return StatusCode((int)response.Type, response);
}

[HttpGet]
public async Task<IActionResult> GetAuthorized()
{
var response = await _authenticationService.GetAuthorized();
return StatusCode((int)response.Type, response);
}
}
15 changes: 4 additions & 11 deletions mohaymen-codestar-Team02/Controllers/DataAdminController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using mohaymen_codestar_Team02.Data;
using mohaymen_codestar_Team02.Dto;
using mohaymen_codestar_Team02.Dto.GraphDTO;
using mohaymen_codestar_Team02.Dto.StoreDataDto;
using mohaymen_codestar_Team02.Models;
Expand All @@ -10,25 +9,25 @@

namespace mohaymen_codestar_Team02.Controllers;

[ApiController]
[Authorize]
public class DataAdminController : ControllerBase
{
private readonly IDataAdminService _dataAdminService;
private readonly IFileReader _fileReader;
private readonly IGraphService _graphService;

public DataAdminController(IDataAdminService dataAdminService,
IFileReader fileReader, IGraphService graphService)
IFileReader fileReader)
{
_dataAdminService = dataAdminService;
_fileReader = fileReader;
_graphService = graphService;
_dataAdminService = dataAdminService;
}

[HttpPost("DataSets")]
public async Task<IActionResult> StoreNewDataSet([FromForm] StoreDataDto storeDataDto)
{
//Todo SystemAdmin and DataAdmin
try
{
var edgeFile = _fileReader.Read(storeDataDto.EdgeFile);
Expand All @@ -48,16 +47,13 @@ public IActionResult GetDataSetsList()
{
var response = _dataAdminService.DisplayDataSet();
return StatusCode((int)response.Type, response);

//Todo all Of Them
}

[HttpGet("DataSets/{dataSetName}")]
public async Task<IActionResult> DisplayDataSetAsGraph(string dataSetName,
[FromQuery] string sourceEdgeIdentifierFieldName, [FromQuery] string destinationEdgeIdentifierFieldName,
[FromQuery] string vertexIdentifierFieldName)
{
//Todo all Of Them
ServiceResponse<DisplayGraphDto> response =
await _dataAdminService.DisplayGeraphData(dataSetName, sourceEdgeIdentifierFieldName,
destinationEdgeIdentifierFieldName, vertexIdentifierFieldName);
Expand All @@ -69,16 +65,13 @@ await _dataAdminService.DisplayGeraphData(dataSetName, sourceEdgeIdentifierField
[HttpGet("DataSets/Vertices/{objectId}")]
public async Task<IActionResult> DisplayVertexDetails(string objectId)
{
//Todo all Of Them

var respond = _dataAdminService.GetVertexDetail(objectId);
return StatusCode((int)respond.Type, respond);
}

[HttpGet("DataSets/Edges/{objectId}")]
public async Task<IActionResult> DisplayEdgeDetails(string objectId)
{
//Todo all Of Them
var respond = _dataAdminService.GetEdgeDetail(objectId);
return StatusCode((int)respond.Type, respond);
}
Expand Down
2 changes: 2 additions & 0 deletions mohaymen-codestar-Team02/Controllers/ProfileController.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using mohaymen_codestar_Team02.Dto.User;
using mohaymen_codestar_Team02.Dto.UserDtos;
Expand All @@ -7,6 +8,7 @@
namespace mohaymen_codestar_Team02.Controllers;

[ApiController]
[Authorize]
[Route("user")]
public class ProfileController : ControllerBase
{
Expand Down
27 changes: 27 additions & 0 deletions mohaymen-codestar-Team02/Data/Resources.Designer.cs

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

9 changes: 9 additions & 0 deletions mohaymen-codestar-Team02/Data/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@
<data name="RolesRetrievedMassage" xml:space="preserve">
<value>Roles Retrieved Successfully</value>
</data>
<data name="GetPermissionsSuccessfuly" xml:space="preserve">
<value>Permissions Get Successfuly</value>
</data>
<data name="YourPasswordIsNotValidated" xml:space="preserve">
<value>Your Password Is Not Validated</value>
</data>
<data name="AuthorizedMessage" xml:space="preserve">
<value>Authorized Message</value>
</data>
<data name="GraphFetchedSuccessfully" xml:space="preserve">
<value>GraphFetchedSuccessfully</value>
</data>
Expand Down
8 changes: 8 additions & 0 deletions mohaymen-codestar-Team02/Dto/Permission/GetPermissionDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace mohaymen_codestar_Team02.Dto.Permission;

using Models;

public class GetPermissionDto
{
public List<Permission> Permissions { get; init; }
}
1 change: 0 additions & 1 deletion mohaymen-codestar-Team02/Dto/UserRole/AddUserRoleDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ namespace mohaymen_codestar_Team02.Dto.UserRole;
public class AddUserRoleDto
{
[Required] public string RoleType { get; set; }
[Required] public string Username { get; set; }
}
1 change: 0 additions & 1 deletion mohaymen-codestar-Team02/Dto/UserRole/DeleteUserRoleDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ namespace mohaymen_codestar_Team02.Dto.UserRole;
public class DeleteUserRoleDto
{
[Required] public string RoleType { get; set; }
[Required] public string Username { get; set; }
}
1 change: 0 additions & 1 deletion mohaymen-codestar-Team02/Mapper/AutoMapperProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using mohaymen_codestar_Team02.Dto.Role;
using mohaymen_codestar_Team02.Dto.User;
using mohaymen_codestar_Team02.Dto.UserDtos;
using mohaymen_codestar_Team02.Dto.UserRole;
using mohaymen_codestar_Team02.Models;
using mohaymen_codestar_Team02.Models.EdgeEAV;
using mohaymen_codestar_Team02.Models.VertexEAV;
Expand Down
94 changes: 94 additions & 0 deletions mohaymen-codestar-Team02/Middlewares/SanitizationMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System.Text;
using Ganss.Xss;
using Microsoft.AspNetCore.Mvc.Controllers;
using Newtonsoft.Json;

namespace mohaymen_codestar_Team02.Middlewares;

public class SanitizationMiddleware
{
private readonly RequestDelegate _next;
private readonly HtmlSanitizer _sanitizer;

public SanitizationMiddleware(RequestDelegate next)
{
_next = next;
_sanitizer = new HtmlSanitizer();
}

public async Task InvokeAsync(HttpContext context)
{
if (context.Request.ContentType != null && context.Request.ContentType.Contains("application/json"))
{
context.Request.EnableBuffering();
using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, leaveOpen: true))
{
var body = await reader.ReadToEndAsync();
context.Request.Body.Position = 0;

var type = GetRequestDtoType(context);
if (type != null)
{
var sanitizedBody = SanitizeRequestBody(body, type);
var buffer = Encoding.UTF8.GetBytes(sanitizedBody);

context.Request.Body = new MemoryStream(buffer);
context.Request.Body.Position = 0;
}
}
}

await _next(context);
}

private Type? GetRequestDtoType(HttpContext context)
{
var endpoint = context.GetEndpoint();
var actionDescriptor = endpoint?.Metadata.GetMetadata<ControllerActionDescriptor>();
if (actionDescriptor != null)
{
var parameters = actionDescriptor.Parameters;
var dtoParameter =
parameters.FirstOrDefault(p => p.ParameterType.IsClass && p.ParameterType != typeof(string));
return dtoParameter?.ParameterType;
}

return null;
}

private string SanitizeRequestBody(string body, Type type)
{
object sanitizedDto;
if (type == typeof(List<string>))
{
var dto = JsonConvert.DeserializeObject<IEnumerable<string>>(body);
sanitizedDto = SanitizeEnumerable(dto);
}
else
{
var dto = JsonConvert.DeserializeObject(body, type);
sanitizedDto = SanitizeDto(dto);
}

return JsonConvert.SerializeObject(sanitizedDto);
}

private IEnumerable<string> SanitizeEnumerable(IEnumerable<string> dto)
{
return dto.Select(str => _sanitizer.Sanitize(str));
}

private object SanitizeDto(object dto)
{
var properties = dto.GetType().GetProperties()
.Where(p => p.PropertyType == typeof(string) && p.CanWrite && p.CanRead);

foreach (var property in properties)
{
var value = (string)property.GetValue(dto);
if (value != null) property.SetValue(dto, _sanitizer.Sanitize(value));
}

return dto;
}
}
File renamed without changes.
File renamed without changes.
28 changes: 28 additions & 0 deletions mohaymen-codestar-Team02/Models/Auth/User.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.ComponentModel.DataAnnotations;

namespace mohaymen_codestar_Team02.Models;

public class User
{
[Key] public long UserId { get; init; }

[Required]
[StringLength(50, MinimumLength = 3, ErrorMessage = "Username must be between 3 and 50 characters.")]
[RegularExpression(@"^[a-zA-Z0-9_]*$",
ErrorMessage = "Username can only contain letters, numbers, and underscores.")]
public string? Username { get; set; } = string.Empty;

[Required] [StringLength(64)] public string FirstName { get; set; } = string.Empty;

[Required] [StringLength(64)] public string LastName { get; set; } = string.Empty;

[Required] [EmailAddress] public string Email { get; set; } = string.Empty;

//dont add normal pass
[Required] [StringLength(256)] public byte[] Salt { get; set; }

[Required] [StringLength(256)] public byte[] PasswordHash { get; set; }

public virtual ICollection<UserRole> UserRoles { get; set; }
public virtual ICollection<DataGroup> DataSets { get; set; }
}
File renamed without changes.
Loading

0 comments on commit c9d9105

Please sign in to comment.