Add Identity configuration, DTOs and Mappers

-Configured Identity using a custom User model to manage authentication and authorization, to be used in the project.
- Added multiple DTOs (Data Transfer Objects).
- Added multiple Mappers ( manual mapping).
- Updated AppDbContext and User model to fully integrate with Identity framework for user management.
-Added relationships between models.
Note : no migration yet
This commit is contained in:
2025-01-20 07:17:35 -08:00
parent 2fa9c6fa80
commit 78900ab7ad
22 changed files with 350 additions and 6 deletions

View File

@@ -0,0 +1,9 @@
namespace survey_beta.DTOs.Create
{
public class CreateAnswerDto
{
public string ResponseId { get; set; }
public string QuestionId { get; set; }
public string ChoiceId { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
namespace survey_beta.DTOs.Create
{
public class CreateChoiceDto
{
public string Letter { get; set; }
public string Content { get; set; }
public string QuestionId { get; set; } = Guid.NewGuid().ToString();
}
}

View File

@@ -0,0 +1,9 @@
namespace survey_beta.DTOs.Create
{
public class CreateQuestionDto
{
public string Content { get; set; }
public string SurveyId { get; set; } = Guid.NewGuid().ToString();
public ICollection<CreateChoiceDto> Choices { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
namespace survey_beta.DTOs.Create
{
public class CreateResponseDto
{
public string IpAddress { get; set; }
public string SurveyId { get; set; }
public ICollection<CreateAnswerDto> Answers { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
namespace survey_beta.DTOs.Create
{
public class CreateSurveyDto
{
public string Id { get; set; } = Guid.NewGuid().ToString();
public string Title { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public DateTime ExpirationDate { get; set; }
public ICollection<CreateQuestionDto> Questions { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
namespace survey_beta.DTOs.Create
{
public class CreateUserDto
{
public string? Email { get; set; }
public string? Username { get; set; }
public string? Fullname { get; set; }
public string? Password { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
namespace survey_beta.DTOs.Create
{
public class LoginDto
{
public string UserName { get; set; }
public string Password { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
namespace survey_beta.DTOs.Default
{
public class AnswerDto
{
public string Id { get; set; }
public string ResponseId { get; set; }
public string QuestionId { get; set; }
public string ChoiceId { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
namespace survey_beta.DTOs.Default
{
public class ChoiceDto
{
public string Id { get; set; }
public string Letter { get; set; }
public string Content { get; set; }
public string QuestionId { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
namespace survey_beta.DTOs.Default
{
public class QuestionDto
{
public string Id { get; set; }
public string Content { get; set; }
public string SurveyId { get; set; }
public ICollection<ChoiceDto> Choices { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
namespace survey_beta.DTOs.Default
{
public class ResponseDto
{
public string Id { get; set; }
public string IpAddress { get; set; }
public string SurveyId { get; set; }
public ICollection<AnswerDto> Answers { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
namespace survey_beta.DTOs.Default
{
public class SurveyDto
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public DateTime ExpirationDate { get; set; }
public bool IsPublished { get; set; }
public string AuthorId { get; set; }
public ICollection<QuestionDto> Questions { get; set; }
public ICollection<ResponseDto> Responses { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
namespace survey_beta.DTOs.Default
{
public class UserDto
{
public string? Id { get; set; }
public string? Email { get; set; }
public string? Username { get; set; }
public string? Fullname { get; set; }
public ICollection<SurveyDto> AuthoredSurveys { get; set; }
}
}

View File

@@ -1,10 +1,13 @@
using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using survey_beta.Models; using survey_beta.Models;
namespace survey_beta.DataBaseContext namespace survey_beta.DataBaseContext
{ {
public class AppDbContext : DbContext public class AppDbContext : IdentityDbContext<User>
{ {
public DbSet<User> Users { get; set; } public override DbSet<User> Users { get; set; }
public DbSet<Survey> Surveys { get; set; } public DbSet<Survey> Surveys { get; set; }
public DbSet<Question> Questions { get; set; } public DbSet<Question> Questions { get; set; }
public DbSet<Choice> Choices { get; set; } public DbSet<Choice> Choices { get; set; }

View File

@@ -0,0 +1,30 @@
using survey_beta.DTOs.Create;
using survey_beta.DTOs.Default;
using survey_beta.Models;
namespace survey_beta.Mappers
{
public class AnswerMapper
{
public static AnswerDto ToDto(Answer answer)
{
return new AnswerDto
{
Id = answer.Id,
ResponseId = answer.ResponseId,
QuestionId = answer.QuestionId,
ChoiceId = answer.ChoiceId
};
}
public static Answer ToEntity(CreateAnswerDto dto)
{
return new Answer
{
Id = Guid.NewGuid().ToString(),
ResponseId = dto.ResponseId,
QuestionId = dto.QuestionId,
ChoiceId = dto.ChoiceId
};
}
}
}

View File

@@ -0,0 +1,31 @@
using survey_beta.DTOs.Create;
using survey_beta.DTOs.Default;
using survey_beta.Models;
namespace survey_beta.Mappers
{
public class ChoiceMapper
{
public static ChoiceDto ToDto(Choice choice)
{
return new ChoiceDto
{
Id = choice.Id,
Letter = choice.Letter,
Content = choice.Content,
QuestionId = choice.QuestionId
};
}
public static Choice ToEntity(CreateChoiceDto dto)
{
return new Choice
{
Id = Guid.NewGuid().ToString(),
Letter = dto.Letter,
Content = dto.Content,
QuestionId = dto.QuestionId
};
}
}
}

View File

@@ -0,0 +1,29 @@
using survey_beta.DTOs.Create;
using survey_beta.DTOs.Default;
using survey_beta.Models;
namespace survey_beta.Mappers
{
public class QuestionMapper
{
public static QuestionDto ToDto(Question question)
{
return new QuestionDto
{
Id = question.Id,
Content = question.Content,
SurveyId = question.SurveyId
};
}
public static Question ToEntity(CreateQuestionDto dto)
{
return new Question
{
Id = Guid.NewGuid().ToString(),
Content = dto.Content,
SurveyId = dto.SurveyId
};
}
}
}

View File

@@ -0,0 +1,29 @@
using survey_beta.DTOs.Create;
using survey_beta.DTOs.Default;
using survey_beta.Models;
namespace survey_beta.Mappers
{
public class ResponseMapper
{
public static ResponseDto ToDto(Response response)
{
return new ResponseDto
{
Id = response.Id,
IpAddress = response.IpAddress,
SurveyId = response.SurveyId
};
}
public static Response ToEntity(CreateResponseDto dto)
{
return new Response
{
Id = Guid.NewGuid().ToString(),
IpAddress = dto.IpAddress,
SurveyId = dto.SurveyId
};
}
}
}

View File

@@ -0,0 +1,37 @@
using survey_beta.DTOs.Create;
using survey_beta.DTOs.Default;
using survey_beta.Models;
namespace survey_beta.Mappers
{
public class SurveyMapper
{
public static SurveyDto ToDto(Survey survey)
{
return new SurveyDto
{
Id = survey.Id,
Title = survey.Title,
Description = survey.Description,
Category = survey.Category,
ExpirationDate = survey.ExpirationDate,
IsPublished = survey.IsPublished,
AuthorId = survey.AuthorId
};
}
public static Survey ToEntity(CreateSurveyDto dto, string authorId)
{
return new Survey
{
Id = Guid.NewGuid().ToString(),
Title = dto.Title,
Description = dto.Description,
Category = dto.Category,
ExpirationDate = dto.ExpirationDate,
IsPublished = false,
AuthorId = authorId
};
}
}
}

View File

@@ -0,0 +1,42 @@
using survey_beta.DTOs.Create;
using survey_beta.DTOs.Default;
using survey_beta.Models;
using System.Security.Cryptography;
namespace survey_beta.Mappers
{
public class UserMapper
{
public static UserDto ToDto(User user)
{
return new UserDto
{
Id = user.Id,
Email = user.Email,
Username = user.Username,
Fullname = user.Fullname
};
}
public static User ToEntity(CreateUserDto dto)
{
return new User
{
Id = Guid.NewGuid().ToString(),
Email = dto.Email,
Username = dto.Username,
Fullname = dto.Fullname,
PasswordHash = HashPassword(dto.Password)
};
}
public static string HashPassword(string password)
{
using (var sha256 = SHA256.Create())
{
var passwordBytes = System.Text.Encoding.UTF8.GetBytes(password);
var hashBytes = sha256.ComputeHash(passwordBytes);
return Convert.ToBase64String(hashBytes);
}
}
}
}

View File

@@ -1,6 +1,8 @@
namespace survey_beta.Models using Microsoft.AspNetCore.Identity;
namespace survey_beta.Models
{ {
public class User public class User : IdentityUser
{ {
public string? Id { get; set; } public string? Id { get; set; }
public string? Username { get; set; } public string? Username { get; set; }

View File

@@ -1,21 +1,30 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using survey_beta.DataBaseContext; using survey_beta.DataBaseContext;
using survey_beta.Models;
using survey_beta.Services;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// Add services to the container // Add services to the container
builder.Services.AddDbContext<AppDbContext>(options => builder.Services.AddDbContext<AppDbContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"))); options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddControllers(); builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
builder.Services.AddIdentity<User, IdentityRole>()
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
builder.Services.AddScoped<UserService>();
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();