From a851adfac47a26cae83e9161d37902a219e5ebf3 Mon Sep 17 00:00:00 2001 From: Danail Dimitrov Date: Sun, 21 Feb 2021 22:21:08 +0200 Subject: model update for rating --- .../Configurations/Extensions/ConfigureDependencyInjection.cs | 2 +- src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/Web/DevHive.Web/Configurations') diff --git a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs index c547951..153b17f 100644 --- a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs +++ b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs @@ -32,7 +32,7 @@ namespace DevHive.Web.Configurations.Extensions cloudName: configuration.GetSection("Cloud").GetSection("cloudName").Value, apiKey: configuration.GetSection("Cloud").GetSection("apiKey").Value, apiSecret: configuration.GetSection("Cloud").GetSection("apiSecret").Value)); - services.AddTransient(); + services.AddTransient(); } } } diff --git a/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs b/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs index a29e06c..1b43b2b 100644 --- a/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs +++ b/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs @@ -8,9 +8,9 @@ namespace DevHive.Web.Configurations.Mapping { public RatingMappings() { - CreateMap(); + CreateMap(); - CreateMap(); + CreateMap(); } } } -- cgit v1.2.3 From d841eada42e0f1f08f488a24752d2f2ae090cb53 Mon Sep 17 00:00:00 2001 From: transtrike Date: Thu, 25 Feb 2021 18:51:29 +0200 Subject: Initial Swagger configuration setup --- .../Configurations/Extensions/ConfigureSwagger.cs | 36 ++++++++++++++++++++-- src/Web/DevHive.Web/DevHive.Web.csproj | 3 +- 2 files changed, 35 insertions(+), 4 deletions(-) (limited to 'src/Web/DevHive.Web/Configurations') diff --git a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureSwagger.cs b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureSwagger.cs index a0641ab..bfa44b0 100644 --- a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureSwagger.cs +++ b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureSwagger.cs @@ -1,23 +1,53 @@ +using System; +using System.IO; +using System.Linq; +using System.Reflection; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; namespace DevHive.Web.Configurations.Extensions { public static class SwaggerExtensions { +#pragma warning disable S1075 + private const string LicenseName = "GPL-3.0 License"; + private const string LicenseUri = "https://github.com/Team-Kaleidoscope/DevHive/blob/main/LICENSE"; + private const string TermsOfServiceUri = "https://example.com/terms"; +#pragma warning restore S1075 + public static void SwaggerConfiguration(this IServiceCollection services) { services.AddSwaggerGen(c => { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "API", Version = "v1" }); + c.SwaggerDoc("v0.1", new OpenApiInfo + { + Version = "v0.1", + Title = "API", + Description = "DevHive Social Media's first official API release", + TermsOfService = new Uri(TermsOfServiceUri), + License = new OpenApiLicense + { + Name = LicenseName, + Url = new Uri(LicenseUri) + } + }); + + string xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; + string xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); + c.IncludeXmlComments(xmlPath); }); } public static void UseSwaggerConfiguration(this IApplicationBuilder app) { app.UseSwagger(); - app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "API v1")); + app.UseSwaggerUI(c => + { + c.SwaggerEndpoint("/swagger/v0.1/swagger.json", "v0.1"); + }); } } -} \ No newline at end of file +} diff --git a/src/Web/DevHive.Web/DevHive.Web.csproj b/src/Web/DevHive.Web/DevHive.Web.csproj index 53f354e..6956613 100644 --- a/src/Web/DevHive.Web/DevHive.Web.csproj +++ b/src/Web/DevHive.Web/DevHive.Web.csproj @@ -5,6 +5,7 @@ true latest + true @@ -29,4 +30,4 @@ - \ No newline at end of file + -- cgit v1.2.3 From 42f4506395d6b9e7593253856a21b2b536e18df5 Mon Sep 17 00:00:00 2001 From: Danail Dimitrov Date: Thu, 25 Feb 2021 22:49:00 +0200 Subject: Adding RatePost functionality --- .../DevHive.Data/Interfaces/IRatingRepository.cs | 1 + .../20210225193352_rating_migration.Designer.cs | 678 +++++++++++++++++++++ .../Migrations/20210225193352_rating_migration.cs | 139 +++++ .../Migrations/DevHiveContextModelSnapshot.cs | 31 +- .../DevHive.Data/Repositories/PostRepository.cs | 2 +- .../DevHive.Data/Repositories/RatingRepository.cs | 7 + .../Post/Rating/UpdateRatingServiceModel.cs | 17 + .../Configurations/Mapping/RatingMappings.cs | 1 + .../DevHive.Services/Interfaces/IRatingService.cs | 2 +- .../DevHive.Services/Services/RatingService.cs | 44 +- .../Rating/CreateRatingWebModel.cs | 11 + .../DevHive.Web.Models/Rating/RatePostWebModel.cs | 11 - .../Configurations/Mapping/RatingMappings.cs | 2 +- src/Web/DevHive.Web/Controllers/RateController.cs | 40 -- .../DevHive.Web/Controllers/RatingController.cs | 42 ++ src/Web/DevHive.Web/DevHive.Web.csproj | 3 +- 16 files changed, 940 insertions(+), 91 deletions(-) create mode 100644 src/Data/DevHive.Data/Migrations/20210225193352_rating_migration.Designer.cs create mode 100644 src/Data/DevHive.Data/Migrations/20210225193352_rating_migration.cs create mode 100644 src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs create mode 100644 src/Web/DevHive.Web.Models/Rating/CreateRatingWebModel.cs delete mode 100644 src/Web/DevHive.Web.Models/Rating/RatePostWebModel.cs delete mode 100644 src/Web/DevHive.Web/Controllers/RateController.cs create mode 100644 src/Web/DevHive.Web/Controllers/RatingController.cs (limited to 'src/Web/DevHive.Web/Configurations') diff --git a/src/Data/DevHive.Data/Interfaces/IRatingRepository.cs b/src/Data/DevHive.Data/Interfaces/IRatingRepository.cs index c8636b6..4cc34c8 100644 --- a/src/Data/DevHive.Data/Interfaces/IRatingRepository.cs +++ b/src/Data/DevHive.Data/Interfaces/IRatingRepository.cs @@ -10,5 +10,6 @@ namespace DevHive.Data.Interfaces { Task> GetRatingsByPostId(Guid postId); Task UserRatedPost(Guid userId, Guid postId); + Task GetRatingByUserAndPostId(Guid userId, Guid postId); } } diff --git a/src/Data/DevHive.Data/Migrations/20210225193352_rating_migration.Designer.cs b/src/Data/DevHive.Data/Migrations/20210225193352_rating_migration.Designer.cs new file mode 100644 index 0000000..c0b67a6 --- /dev/null +++ b/src/Data/DevHive.Data/Migrations/20210225193352_rating_migration.Designer.cs @@ -0,0 +1,678 @@ +// +using System; +using DevHive.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace DevHive.Data.Migrations +{ + [DbContext(typeof(DevHiveContext))] + [Migration("20210225193352_rating_migration")] + partial class rating_migration + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.3") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + modelBuilder.Entity("DevHive.Data.Models.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatorId") + .HasColumnType("uuid"); + + b.Property("Message") + .HasColumnType("text"); + + b.Property("PostId") + .HasColumnType("uuid"); + + b.Property("TimeCreated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.HasIndex("PostId"); + + b.ToTable("Comments"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Language", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Languages"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatorId") + .HasColumnType("uuid"); + + b.Property("CurrentRating") + .HasColumnType("integer"); + + b.Property("Message") + .HasColumnType("text"); + + b.Property("TimeCreated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("PictureURL") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("ProfilePicture"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("IsLike") + .HasColumnType("boolean"); + + b.Property("PostId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("Rating"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Relational.PostAttachments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("FileUrl") + .HasColumnType("text"); + + b.Property("PostId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.ToTable("PostAttachments"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Relational.RatedPost", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("PostId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "PostId"); + + b.HasIndex("PostId"); + + b.ToTable("RatedPosts"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Relational.UserRate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Liked") + .HasColumnType("boolean"); + + b.Property("PostId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("UserRates"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Technology", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Technologies"); + }); + + modelBuilder.Entity("DevHive.Data.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("FirstName") + .HasColumnType("text"); + + b.Property("LastName") + .HasColumnType("text"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.HasIndex("UserId"); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("LanguageUser", b => + { + b.Property("LanguagesId") + .HasColumnType("uuid"); + + b.Property("UsersId") + .HasColumnType("uuid"); + + b.HasKey("LanguagesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("LanguageUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.Property("RolesId") + .HasColumnType("uuid"); + + b.Property("UsersId") + .HasColumnType("uuid"); + + b.HasKey("RolesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("RoleUser"); + }); + + modelBuilder.Entity("TechnologyUser", b => + { + b.Property("TechnologiesId") + .HasColumnType("uuid"); + + b.Property("UsersId") + .HasColumnType("uuid"); + + b.HasKey("TechnologiesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("TechnologyUser"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Comment", b => + { + b.HasOne("DevHive.Data.Models.User", "Creator") + .WithMany("Comments") + .HasForeignKey("CreatorId"); + + b.HasOne("DevHive.Data.Models.Post", "Post") + .WithMany("Comments") + .HasForeignKey("PostId"); + + b.Navigation("Creator"); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.HasOne("DevHive.Data.Models.User", "Creator") + .WithMany("Posts") + .HasForeignKey("CreatorId"); + + b.Navigation("Creator"); + }); + + modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b => + { + b.HasOne("DevHive.Data.Models.User", "User") + .WithOne("ProfilePicture") + .HasForeignKey("DevHive.Data.Models.ProfilePicture", "UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Rating", b => + { + b.HasOne("DevHive.Data.Models.Post", "Post") + .WithMany("Ratings") + .HasForeignKey("PostId"); + + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Post"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Relational.PostAttachments", b => + { + b.HasOne("DevHive.Data.Models.Post", "Post") + .WithMany("Attachments") + .HasForeignKey("PostId"); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Relational.RatedPost", b => + { + b.HasOne("DevHive.Data.Models.Post", "Post") + .WithMany() + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany("RatedPosts") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Post"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Relational.UserRate", b => + { + b.HasOne("DevHive.Data.Models.Post", "Post") + .WithMany() + .HasForeignKey("PostId"); + + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Post"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DevHive.Data.Models.User", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany("Friends") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("LanguageUser", b => + { + b.HasOne("DevHive.Data.Models.Language", null) + .WithMany() + .HasForeignKey("LanguagesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("DevHive.Data.Models.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("DevHive.Data.Models.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.HasOne("DevHive.Data.Models.Role", null) + .WithMany() + .HasForeignKey("RolesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("TechnologyUser", b => + { + b.HasOne("DevHive.Data.Models.Technology", null) + .WithMany() + .HasForeignKey("TechnologiesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.Navigation("Attachments"); + + b.Navigation("Comments"); + + b.Navigation("Ratings"); + }); + + modelBuilder.Entity("DevHive.Data.Models.User", b => + { + b.Navigation("Comments"); + + b.Navigation("Friends"); + + b.Navigation("Posts"); + + b.Navigation("ProfilePicture"); + + b.Navigation("RatedPosts"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Data/DevHive.Data/Migrations/20210225193352_rating_migration.cs b/src/Data/DevHive.Data/Migrations/20210225193352_rating_migration.cs new file mode 100644 index 0000000..da81cdc --- /dev/null +++ b/src/Data/DevHive.Data/Migrations/20210225193352_rating_migration.cs @@ -0,0 +1,139 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace DevHive.Data.Migrations +{ + public partial class rating_migration : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Rating_Posts_PostId", + table: "Rating"); + + migrationBuilder.DropIndex( + name: "IX_Rating_PostId", + table: "Rating"); + + migrationBuilder.DropColumn( + name: "Rate", + table: "Rating"); + + migrationBuilder.AlterColumn( + name: "PostId", + table: "Rating", + type: "uuid", + nullable: true, + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AddColumn( + name: "IsLike", + table: "Rating", + type: "boolean", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "UserId", + table: "Rating", + type: "uuid", + nullable: true); + + migrationBuilder.AddColumn( + name: "CurrentRating", + table: "Posts", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.CreateIndex( + name: "IX_Rating_PostId", + table: "Rating", + column: "PostId"); + + migrationBuilder.CreateIndex( + name: "IX_Rating_UserId", + table: "Rating", + column: "UserId"); + + migrationBuilder.AddForeignKey( + name: "FK_Rating_AspNetUsers_UserId", + table: "Rating", + column: "UserId", + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_Rating_Posts_PostId", + table: "Rating", + column: "PostId", + principalTable: "Posts", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Rating_AspNetUsers_UserId", + table: "Rating"); + + migrationBuilder.DropForeignKey( + name: "FK_Rating_Posts_PostId", + table: "Rating"); + + migrationBuilder.DropIndex( + name: "IX_Rating_PostId", + table: "Rating"); + + migrationBuilder.DropIndex( + name: "IX_Rating_UserId", + table: "Rating"); + + migrationBuilder.DropColumn( + name: "IsLike", + table: "Rating"); + + migrationBuilder.DropColumn( + name: "UserId", + table: "Rating"); + + migrationBuilder.DropColumn( + name: "CurrentRating", + table: "Posts"); + + migrationBuilder.AlterColumn( + name: "PostId", + table: "Rating", + type: "uuid", + nullable: false, + defaultValue: new Guid("00000000-0000-0000-0000-000000000000"), + oldClrType: typeof(Guid), + oldType: "uuid", + oldNullable: true); + + migrationBuilder.AddColumn( + name: "Rate", + table: "Rating", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.CreateIndex( + name: "IX_Rating_PostId", + table: "Rating", + column: "PostId", + unique: true); + + migrationBuilder.AddForeignKey( + name: "FK_Rating_Posts_PostId", + table: "Rating", + column: "PostId", + principalTable: "Posts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/Data/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs b/src/Data/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs index 8db3abf..a722cb2 100644 --- a/src/Data/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs +++ b/src/Data/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs @@ -69,6 +69,9 @@ namespace DevHive.Data.Migrations b.Property("CreatorId") .HasColumnType("uuid"); + b.Property("CurrentRating") + .HasColumnType("integer"); + b.Property("Message") .HasColumnType("text"); @@ -108,16 +111,20 @@ namespace DevHive.Data.Migrations .ValueGeneratedOnAdd() .HasColumnType("uuid"); - b.Property("PostId") + b.Property("IsLike") + .HasColumnType("boolean"); + + b.Property("PostId") .HasColumnType("uuid"); - b.Property("Rate") - .HasColumnType("integer"); + b.Property("UserId") + .HasColumnType("uuid"); b.HasKey("Id"); - b.HasIndex("PostId") - .IsUnique(); + b.HasIndex("PostId"); + + b.HasIndex("UserId"); b.ToTable("Rating"); }); @@ -484,12 +491,16 @@ namespace DevHive.Data.Migrations modelBuilder.Entity("DevHive.Data.Models.Rating", b => { b.HasOne("DevHive.Data.Models.Post", "Post") - .WithOne("Rating") - .HasForeignKey("DevHive.Data.Models.Rating", "PostId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .WithMany("Ratings") + .HasForeignKey("PostId"); + + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); b.Navigation("Post"); + + b.Navigation("User"); }); modelBuilder.Entity("DevHive.Data.Models.Relational.PostAttachments", b => @@ -644,7 +655,7 @@ namespace DevHive.Data.Migrations b.Navigation("Comments"); - b.Navigation("Rating"); + b.Navigation("Ratings"); }); modelBuilder.Entity("DevHive.Data.Models.User", b => diff --git a/src/Data/DevHive.Data/Repositories/PostRepository.cs b/src/Data/DevHive.Data/Repositories/PostRepository.cs index 0ab1afb..0a88cf2 100644 --- a/src/Data/DevHive.Data/Repositories/PostRepository.cs +++ b/src/Data/DevHive.Data/Repositories/PostRepository.cs @@ -36,7 +36,7 @@ namespace DevHive.Data.Repositories .Include(x => x.Comments) .Include(x => x.Creator) .Include(x => x.Attachments) - .Include(x => x.CurrentRating) + .Include(x => x.Ratings) .FirstOrDefaultAsync(x => x.Id == id); } diff --git a/src/Data/DevHive.Data/Repositories/RatingRepository.cs b/src/Data/DevHive.Data/Repositories/RatingRepository.cs index 2f56aee..4db208e 100644 --- a/src/Data/DevHive.Data/Repositories/RatingRepository.cs +++ b/src/Data/DevHive.Data/Repositories/RatingRepository.cs @@ -32,5 +32,12 @@ namespace DevHive.Data.Repositories .Where(x => x.Post.Id == postId) .AnyAsync(x => x.User.Id == userId); } + + public async Task GetRatingByUserAndPostId(Guid userId, Guid postId) + { + return await this._context.Rating + .FirstOrDefaultAsync(x => x.Post.Id == postId && x.User.Id == userId); + } } } + diff --git a/src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs b/src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs new file mode 100644 index 0000000..8710751 --- /dev/null +++ b/src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DevHive.Services.Models.Post.Rating +{ + public class UpdateRatingServiceModel + { + public Guid Id { get; set; } + + public Guid UserId { get; set; } + + public bool IsLike { get; set; } + } +} diff --git a/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs b/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs index fefa6d8..6d21de0 100644 --- a/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs +++ b/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs @@ -8,6 +8,7 @@ namespace DevHive.Services.Configurations.Mapping { public RatingMappings() { + CreateMap(); } } } diff --git a/src/Services/DevHive.Services/Interfaces/IRatingService.cs b/src/Services/DevHive.Services/Interfaces/IRatingService.cs index adb4313..5dea04f 100644 --- a/src/Services/DevHive.Services/Interfaces/IRatingService.cs +++ b/src/Services/DevHive.Services/Interfaces/IRatingService.cs @@ -7,7 +7,7 @@ namespace DevHive.Services.Interfaces { public interface IRatingService { - Task RatePost(CreateRatingServiceModel ratePostServiceModel); + Task RatePost(CreateRatingServiceModel ratePostServiceModel); bool HasUserRatedThisPost(User user, Post post); } diff --git a/src/Services/DevHive.Services/Services/RatingService.cs b/src/Services/DevHive.Services/Services/RatingService.cs index 45ff7c0..a4d04b1 100644 --- a/src/Services/DevHive.Services/Services/RatingService.cs +++ b/src/Services/DevHive.Services/Services/RatingService.cs @@ -24,29 +24,31 @@ namespace DevHive.Services.Services this._mapper = mapper; } - public async Task RatePost(CreateRatingServiceModel ratePostServiceModel) + public async Task RatePost(CreateRatingServiceModel createRatingServiceModel) { - throw new NotImplementedException(); - // if (!await this._postRepository.DoesPostExist(ratePostServiceModel.PostId)) - // throw new ArgumentException("Post does not exist!"); + if (!await this._postRepository.DoesPostExist(createRatingServiceModel.PostId)) + throw new ArgumentException("Post does not exist!"); - // if (!await this._userRepository.DoesUserExistAsync(ratePostServiceModel.UserId)) - // throw new ArgumentException("User does not exist!"); + if (await this._ratingRepository.UserRatedPost(createRatingServiceModel.UserId, createRatingServiceModel.PostId)) + throw new ArgumentException("User already rated the post!"); - // Post post = await this._postRepository.GetByIdAsync(ratePostServiceModel.PostId); - // User user = await this._userRepository.GetByIdAsync(ratePostServiceModel.UserId); + Rating rating = this._mapper.Map(createRatingServiceModel); - // if (this.HasUserRatedThisPost(user, post)) - // throw new ArgumentException("You can't rate the same post more then one(duh, amigo)"); + User user = await this._userRepository.GetByIdAsync(createRatingServiceModel.UserId); + Post post = await this._postRepository.GetByIdAsync(createRatingServiceModel.PostId); + rating.User = user; + rating.Post = post; - // this.Rate(user, post, ratePostServiceModel.Liked); + bool success = await this._ratingRepository.AddAsync(rating); - // bool success = await this._ratingRepository.EditAsync(post.Rating.Id, post.Rating); - // if (!success) - // throw new InvalidOperationException("Unable to rate the post!"); + if (success) + { + Rating newRating = await this._ratingRepository.GetRatingByUserAndPostId(rating.User.Id, rating.Post.Id); - // Rating newRating = await this._ratingRepository.GetByIdAsync(post.Rating.Id); - // return this._mapper.Map(newRating); + return newRating.Id; + } + else + return Guid.Empty; } public async Task RemoveUserRateFromPost(Guid userId, Guid postId) @@ -66,15 +68,5 @@ namespace DevHive.Services.Services // .Any(x => x.Id == user.Id); } - private void Rate(User user, Post post, bool liked) - { - throw new NotImplementedException(); - // if (liked) - // post.Rating.Rate++; - // else - // post.Rating.Rate--; - - // post.Rating.UsersThatRated.Add(user); - } } } diff --git a/src/Web/DevHive.Web.Models/Rating/CreateRatingWebModel.cs b/src/Web/DevHive.Web.Models/Rating/CreateRatingWebModel.cs new file mode 100644 index 0000000..010e04e --- /dev/null +++ b/src/Web/DevHive.Web.Models/Rating/CreateRatingWebModel.cs @@ -0,0 +1,11 @@ +using System; + +namespace DevHive.Web.Models.Rating +{ + public class CreateRatingWebModel + { + public Guid PostId { get; set; } + + public bool IsLiked { get; set; } + } +} diff --git a/src/Web/DevHive.Web.Models/Rating/RatePostWebModel.cs b/src/Web/DevHive.Web.Models/Rating/RatePostWebModel.cs deleted file mode 100644 index cbba4ab..0000000 --- a/src/Web/DevHive.Web.Models/Rating/RatePostWebModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace DevHive.Web.Models.Rating -{ - public class RatePostWebModel - { - public Guid PostId { get; set; } - - public bool Liked { get; set; } - } -} diff --git a/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs b/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs index 1b43b2b..c8b7353 100644 --- a/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs +++ b/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs @@ -8,7 +8,7 @@ namespace DevHive.Web.Configurations.Mapping { public RatingMappings() { - CreateMap(); + CreateMap(); CreateMap(); } diff --git a/src/Web/DevHive.Web/Controllers/RateController.cs b/src/Web/DevHive.Web/Controllers/RateController.cs deleted file mode 100644 index 7f8a95f..0000000 --- a/src/Web/DevHive.Web/Controllers/RateController.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Threading.Tasks; -using AutoMapper; -using DevHive.Services.Interfaces; -using DevHive.Services.Models.Post.Rating; -using DevHive.Web.Models.Rating; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; - -namespace DevHive.Web.Controllers -{ - [ApiController] - [Route("api/[controller]")] - public class RateController - { - private readonly IRatingService _rateService; - private readonly IUserService _userService; - private readonly IMapper _mapper; - - public RateController(IRatingService rateService, IUserService userService, IMapper mapper) - { - this._rateService = rateService; - this._userService = userService; - this._mapper = mapper; - } - - [HttpPost] - [Authorize(Roles = "Admin,User")] - public async Task RatePost(Guid userId, [FromBody] RatePostWebModel ratePostWebModel, [FromHeader] string authorization) - { - CreateRatingServiceModel ratePostServiceModel = this._mapper.Map(ratePostWebModel); - ratePostServiceModel.UserId = userId; - - ReadRatingServiceModel readPostRatingServiceModel = await this._rateService.RatePost(ratePostServiceModel); - ReadPostRatingWebModel readPostRatingWebModel = this._mapper.Map(readPostRatingServiceModel); - - return new OkObjectResult(readPostRatingWebModel); - } - } -} diff --git a/src/Web/DevHive.Web/Controllers/RatingController.cs b/src/Web/DevHive.Web/Controllers/RatingController.cs new file mode 100644 index 0000000..673aee1 --- /dev/null +++ b/src/Web/DevHive.Web/Controllers/RatingController.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading.Tasks; +using AutoMapper; +using DevHive.Services.Interfaces; +using DevHive.Services.Models.Post.Rating; +using DevHive.Web.Models.Rating; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace DevHive.Web.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class RatingController + { + private readonly IRatingService _rateService; + private readonly IUserService _userService; + private readonly IMapper _mapper; + + public RatingController(IRatingService rateService, IUserService userService, IMapper mapper) + { + this._rateService = rateService; + this._userService = userService; + this._mapper = mapper; + } + + [HttpPost] + [Authorize(Roles = "Admin,User")] + public async Task RatePost(Guid userId, [FromBody] CreateRatingWebModel createRatingWebModel, [FromHeader] string authorization) + { + CreateRatingServiceModel ratePostServiceModel = this._mapper.Map(createRatingWebModel); + ratePostServiceModel.UserId = userId; + + Guid id = await this._rateService.RatePost(ratePostServiceModel); + + if (Guid.Empty == id) + return new BadRequestResult(); + + return new OkObjectResult(id); + } + } +} diff --git a/src/Web/DevHive.Web/DevHive.Web.csproj b/src/Web/DevHive.Web/DevHive.Web.csproj index 6511c37..7c0b262 100644 --- a/src/Web/DevHive.Web/DevHive.Web.csproj +++ b/src/Web/DevHive.Web/DevHive.Web.csproj @@ -5,6 +5,7 @@ true latest + true @@ -25,4 +26,4 @@ - \ No newline at end of file + -- cgit v1.2.3 From 8e0038628e866ac5ce716e7971e150d2a8f23f4c Mon Sep 17 00:00:00 2001 From: Danail Dimitrov Date: Fri, 26 Feb 2021 09:25:24 +0200 Subject: Added GetById for rating --- .../DevHive.Data/Repositories/RatingRepository.cs | 7 ++++ .../Post/Rating/ReadRatingServiceModel.cs | 4 +- .../Post/Rating/UpdateRatingServiceModel.cs | 4 -- .../Configurations/Mapping/RatingMappings.cs | 2 + .../DevHive.Services/Interfaces/IRatingService.cs | 8 +++- .../DevHive.Services/Services/RatingService.cs | 45 +++++++++++++++++----- .../Rating/ReadPostRatingWebModel.cs | 15 -------- .../Rating/ReadRatingWebModel.cs | 15 ++++++++ .../Configurations/Mapping/RatingMappings.cs | 2 +- .../DevHive.Web/Controllers/RatingController.cs | 9 +++++ 10 files changed, 77 insertions(+), 34 deletions(-) delete mode 100644 src/Web/DevHive.Web.Models/Rating/ReadPostRatingWebModel.cs create mode 100644 src/Web/DevHive.Web.Models/Rating/ReadRatingWebModel.cs (limited to 'src/Web/DevHive.Web/Configurations') diff --git a/src/Data/DevHive.Data/Repositories/RatingRepository.cs b/src/Data/DevHive.Data/Repositories/RatingRepository.cs index 4db208e..02f92c0 100644 --- a/src/Data/DevHive.Data/Repositories/RatingRepository.cs +++ b/src/Data/DevHive.Data/Repositories/RatingRepository.cs @@ -20,6 +20,13 @@ namespace DevHive.Data.Repositories this._postRepository = postRepository; } + public override async Task GetByIdAsync(Guid id) + { + return await this._context.Rating + .Include(x => x.User) + .Include(x => x.Post) + .FirstOrDefaultAsync(x => x.Id == id); + } public async Task> GetRatingsByPostId(Guid postId) { return await this._context.Rating diff --git a/src/Services/DevHive.Services.Models/Post/Rating/ReadRatingServiceModel.cs b/src/Services/DevHive.Services.Models/Post/Rating/ReadRatingServiceModel.cs index dbc7ecc..86b4957 100644 --- a/src/Services/DevHive.Services.Models/Post/Rating/ReadRatingServiceModel.cs +++ b/src/Services/DevHive.Services.Models/Post/Rating/ReadRatingServiceModel.cs @@ -8,8 +8,8 @@ namespace DevHive.Services.Models.Post.Rating public Guid PostId { get; set; } - public int Likes { get; set; } + public Guid UserId { get; set; } - public int Dislikes { get; set; } + public bool IsLike { get; set; } } } diff --git a/src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs b/src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs index 8710751..f6233f9 100644 --- a/src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs +++ b/src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace DevHive.Services.Models.Post.Rating { diff --git a/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs b/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs index 6d21de0..7056afa 100644 --- a/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs +++ b/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs @@ -9,6 +9,8 @@ namespace DevHive.Services.Configurations.Mapping public RatingMappings() { CreateMap(); + + CreateMap(); } } } diff --git a/src/Services/DevHive.Services/Interfaces/IRatingService.cs b/src/Services/DevHive.Services/Interfaces/IRatingService.cs index 5dea04f..a554ce3 100644 --- a/src/Services/DevHive.Services/Interfaces/IRatingService.cs +++ b/src/Services/DevHive.Services/Interfaces/IRatingService.cs @@ -7,8 +7,12 @@ namespace DevHive.Services.Interfaces { public interface IRatingService { - Task RatePost(CreateRatingServiceModel ratePostServiceModel); + Task RatePost(CreateRatingServiceModel createRatingServiceModel); - bool HasUserRatedThisPost(User user, Post post); + Task GetRatingById(Guid ratingId); + Task GetUserRateFromPost(Guid userId, Guid postId); + Task HasUserRatedThisPost(Guid userId, Guid postId); + + Task RemoveUserRateFromPost(Guid userId, Guid postId); } } diff --git a/src/Services/DevHive.Services/Services/RatingService.cs b/src/Services/DevHive.Services/Services/RatingService.cs index a4d04b1..e8c3c4c 100644 --- a/src/Services/DevHive.Services/Services/RatingService.cs +++ b/src/Services/DevHive.Services/Services/RatingService.cs @@ -24,6 +24,7 @@ namespace DevHive.Services.Services this._mapper = mapper; } + #region Create public async Task RatePost(CreateRatingServiceModel createRatingServiceModel) { if (!await this._postRepository.DoesPostExist(createRatingServiceModel.PostId)) @@ -50,23 +51,47 @@ namespace DevHive.Services.Services else return Guid.Empty; } + #endregion - public async Task RemoveUserRateFromPost(Guid userId, Guid postId) + #region Read + public async Task GetRatingById(Guid ratingId) { - throw new NotImplementedException(); - // Post post = await this._postRepository.GetByIdAsync(postId); - // User user = await this._userRepository.GetByIdAsync(userId); + Rating rating = await this._ratingRepository.GetByIdAsync(ratingId) ?? + throw new ArgumentException("The rating does not exist"); + + User user = await this._userRepository.GetByIdAsync(rating.User.Id) ?? + throw new ArgumentException("The user does not exist"); + + ReadRatingServiceModel readRatingServiceModel = this._mapper.Map(rating); + readRatingServiceModel.UserId = user.Id; - // if (!this.HasUserRatedThisPost(user, post)) - // throw new ArgumentException("You haven't rated this post, lmao!"); + return readRatingServiceModel; } - public bool HasUserRatedThisPost(User user, Post post) + public async Task GetUserRateFromPost(Guid userId, Guid postId) { - throw new NotImplementedException(); - // return post.Rating.UsersThatRated - // .Any(x => x.Id == user.Id); + Rating rating = await this._ratingRepository.GetRatingByUserAndPostId(userId, postId) ?? + throw new ArgumentException("The rating does not exist"); + + User user = await this._userRepository.GetByIdAsync(rating.User.Id) ?? + throw new ArgumentException("The user does not exist"); + + ReadRatingServiceModel readRatingServiceModel = this._mapper.Map(rating); + readRatingServiceModel.UserId = user.Id; + + return readRatingServiceModel; } + public async Task HasUserRatedThisPost(Guid userId, Guid postId) + { + return await this._ratingRepository + .UserRatedPost(userId, postId); + } + #endregion + + public async Task RemoveUserRateFromPost(Guid userId, Guid postId) + { + throw new NotImplementedException(); + } } } diff --git a/src/Web/DevHive.Web.Models/Rating/ReadPostRatingWebModel.cs b/src/Web/DevHive.Web.Models/Rating/ReadPostRatingWebModel.cs deleted file mode 100644 index 8afd57e..0000000 --- a/src/Web/DevHive.Web.Models/Rating/ReadPostRatingWebModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace DevHive.Web.Models.Rating -{ - public class ReadPostRatingWebModel - { - public Guid Id { get; set; } - - public Guid PostId { get; set; } - - public int Likes { get; set; } - - public int Dislikes { get; set; } - } -} diff --git a/src/Web/DevHive.Web.Models/Rating/ReadRatingWebModel.cs b/src/Web/DevHive.Web.Models/Rating/ReadRatingWebModel.cs new file mode 100644 index 0000000..40f4c6f --- /dev/null +++ b/src/Web/DevHive.Web.Models/Rating/ReadRatingWebModel.cs @@ -0,0 +1,15 @@ +using System; + +namespace DevHive.Web.Models.Rating +{ + public class ReadRatingWebModel + { + public Guid Id { get; set; } + + public Guid PostId { get; set; } + + public Guid UserId { get; set; } + + public bool IsLike { get; set; } + } +} diff --git a/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs b/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs index c8b7353..aabee01 100644 --- a/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs +++ b/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs @@ -10,7 +10,7 @@ namespace DevHive.Web.Configurations.Mapping { CreateMap(); - CreateMap(); + CreateMap(); } } } diff --git a/src/Web/DevHive.Web/Controllers/RatingController.cs b/src/Web/DevHive.Web/Controllers/RatingController.cs index 673aee1..d2a7801 100644 --- a/src/Web/DevHive.Web/Controllers/RatingController.cs +++ b/src/Web/DevHive.Web/Controllers/RatingController.cs @@ -38,5 +38,14 @@ namespace DevHive.Web.Controllers return new OkObjectResult(id); } + + [HttpGet] + public async Task GetRatingById(Guid id) + { + ReadRatingServiceModel readRatingServiceModel = await this._rateService.GetRatingById(id); + ReadRatingWebModel readPostRatingWebModel = this._mapper.Map(readRatingServiceModel); + + return new OkObjectResult(readPostRatingWebModel); + } } } -- cgit v1.2.3 From 379eda6a42fdba0a6ed7e7ae53e0fbf2acd774b6 Mon Sep 17 00:00:00 2001 From: Danail Dimitrov Date: Fri, 26 Feb 2021 23:00:50 +0200 Subject: Adding update layer for rating_system --- src/Data/DevHive.Data.Models/Post.cs | 2 - .../DevHive.Data/Interfaces/IRatingRepository.cs | 2 + .../DevHive.Data/Repositories/RatingRepository.cs | 11 +++-- .../Post/Rating/UpdateRatingServiceModel.cs | 2 + .../Configurations/Mapping/RatingMappings.cs | 2 + .../DevHive.Services/Interfaces/IRatingService.cs | 5 ++- .../DevHive.Services/Services/PostService.cs | 1 - .../DevHive.Services/Services/RatingService.cs | 49 +++++++++++++++------- .../Rating/UpdateRatingWebModel.cs | 15 +++++++ .../Configurations/Mapping/RatingMappings.cs | 2 + .../DevHive.Web/Controllers/RatingController.cs | 22 +++++++++- 11 files changed, 88 insertions(+), 25 deletions(-) create mode 100644 src/Web/DevHive.Web.Models/Rating/UpdateRatingWebModel.cs (limited to 'src/Web/DevHive.Web/Configurations') diff --git a/src/Data/DevHive.Data.Models/Post.cs b/src/Data/DevHive.Data.Models/Post.cs index 716248f..c95a8f1 100644 --- a/src/Data/DevHive.Data.Models/Post.cs +++ b/src/Data/DevHive.Data.Models/Post.cs @@ -21,8 +21,6 @@ namespace DevHive.Data.Models public List Ratings { get; set; } - public int CurrentRating { get; set; } - public List Attachments { get; set; } = new(); } } diff --git a/src/Data/DevHive.Data/Interfaces/IRatingRepository.cs b/src/Data/DevHive.Data/Interfaces/IRatingRepository.cs index 4cc34c8..db37d00 100644 --- a/src/Data/DevHive.Data/Interfaces/IRatingRepository.cs +++ b/src/Data/DevHive.Data/Interfaces/IRatingRepository.cs @@ -11,5 +11,7 @@ namespace DevHive.Data.Interfaces Task> GetRatingsByPostId(Guid postId); Task UserRatedPost(Guid userId, Guid postId); Task GetRatingByUserAndPostId(Guid userId, Guid postId); + + Task DoesRatingExist(Guid id); } } diff --git a/src/Data/DevHive.Data/Repositories/RatingRepository.cs b/src/Data/DevHive.Data/Repositories/RatingRepository.cs index 02f92c0..9bb2368 100644 --- a/src/Data/DevHive.Data/Repositories/RatingRepository.cs +++ b/src/Data/DevHive.Data/Repositories/RatingRepository.cs @@ -32,19 +32,24 @@ namespace DevHive.Data.Repositories return await this._context.Rating .Where(x => x.Post.Id == postId).ToListAsync(); } - public async Task UserRatedPost(Guid userId, Guid postId) { - return await this._context.UserRate + return await this._context.Rating .Where(x => x.Post.Id == postId) .AnyAsync(x => x.User.Id == userId); } - public async Task GetRatingByUserAndPostId(Guid userId, Guid postId) { return await this._context.Rating .FirstOrDefaultAsync(x => x.Post.Id == postId && x.User.Id == userId); } + + public async Task DoesRatingExist(Guid id) + { + return await this._context.Rating + .AsNoTracking() + .AnyAsync(r => r.Id == id); + } } } diff --git a/src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs b/src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs index f6233f9..1ea8d8f 100644 --- a/src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs +++ b/src/Services/DevHive.Services.Models/Post/Rating/UpdateRatingServiceModel.cs @@ -8,6 +8,8 @@ namespace DevHive.Services.Models.Post.Rating public Guid UserId { get; set; } + public Guid PostId { get; set; } + public bool IsLike { get; set; } } } diff --git a/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs b/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs index 7056afa..3ef7d33 100644 --- a/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs +++ b/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs @@ -11,6 +11,8 @@ namespace DevHive.Services.Configurations.Mapping CreateMap(); CreateMap(); + + CreateMap(); } } } diff --git a/src/Services/DevHive.Services/Interfaces/IRatingService.cs b/src/Services/DevHive.Services/Interfaces/IRatingService.cs index a554ce3..601b07e 100644 --- a/src/Services/DevHive.Services/Interfaces/IRatingService.cs +++ b/src/Services/DevHive.Services/Interfaces/IRatingService.cs @@ -10,9 +10,10 @@ namespace DevHive.Services.Interfaces Task RatePost(CreateRatingServiceModel createRatingServiceModel); Task GetRatingById(Guid ratingId); - Task GetUserRateFromPost(Guid userId, Guid postId); Task HasUserRatedThisPost(Guid userId, Guid postId); - Task RemoveUserRateFromPost(Guid userId, Guid postId); + Task UpdateRating(UpdateRatingServiceModel updateRatingServiceModel); + + Task DeleteRating(Guid ratingId); } } diff --git a/src/Services/DevHive.Services/Services/PostService.cs b/src/Services/DevHive.Services/Services/PostService.cs index 4bece90..a3d5117 100644 --- a/src/Services/DevHive.Services/Services/PostService.cs +++ b/src/Services/DevHive.Services/Services/PostService.cs @@ -46,7 +46,6 @@ namespace DevHive.Services.Services post.Creator = await this._userRepository.GetByIdAsync(createPostServiceModel.CreatorId); post.TimeCreated = DateTime.Now; - post.CurrentRating = 0; bool success = await this._postRepository.AddAsync(post); if (success) diff --git a/src/Services/DevHive.Services/Services/RatingService.cs b/src/Services/DevHive.Services/Services/RatingService.cs index e8c3c4c..20080ea 100644 --- a/src/Services/DevHive.Services/Services/RatingService.cs +++ b/src/Services/DevHive.Services/Services/RatingService.cs @@ -68,30 +68,49 @@ namespace DevHive.Services.Services return readRatingServiceModel; } - public async Task GetUserRateFromPost(Guid userId, Guid postId) + public async Task HasUserRatedThisPost(Guid userId, Guid postId) { - Rating rating = await this._ratingRepository.GetRatingByUserAndPostId(userId, postId) ?? - throw new ArgumentException("The rating does not exist"); + return await this._ratingRepository + .UserRatedPost(userId, postId); + } + #endregion - User user = await this._userRepository.GetByIdAsync(rating.User.Id) ?? - throw new ArgumentException("The user does not exist"); + #region Update + public async Task UpdateRating(UpdateRatingServiceModel updateRatingServiceModel) + { + Rating rating = await this._ratingRepository.GetRatingByUserAndPostId(updateRatingServiceModel.UserId, updateRatingServiceModel.PostId) ?? + throw new ArgumentException("Rating does not exist!"); - ReadRatingServiceModel readRatingServiceModel = this._mapper.Map(rating); - readRatingServiceModel.UserId = user.Id; + User user = await this._userRepository.GetByIdAsync(updateRatingServiceModel.UserId) ?? + throw new ArgumentException("User does not exist!"); - return readRatingServiceModel; - } + if (!await this._ratingRepository.UserRatedPost(updateRatingServiceModel.UserId, updateRatingServiceModel.PostId)) + throw new ArgumentException("User has not rated the post!"); - public async Task HasUserRatedThisPost(Guid userId, Guid postId) - { - return await this._ratingRepository - .UserRatedPost(userId, postId); + rating.User = user; + rating.IsLike = updateRatingServiceModel.IsLike; + + bool result = await this._ratingRepository.EditAsync(updateRatingServiceModel.Id, rating); + + if (result) + { + ReadRatingServiceModel readRatingServiceModel = this._mapper.Map(rating); + return readRatingServiceModel; + } + else + return null; } #endregion - public async Task RemoveUserRateFromPost(Guid userId, Guid postId) + #region Delete + public async Task DeleteRating(Guid ratingId) { - throw new NotImplementedException(); + if (!await this._ratingRepository.DoesRatingExist(ratingId)) + throw new ArgumentException("Rating does not exist!"); + + Rating rating = await this._ratingRepository.GetByIdAsync(ratingId); + return await this._ratingRepository.DeleteAsync(rating); } + #endregion } } diff --git a/src/Web/DevHive.Web.Models/Rating/UpdateRatingWebModel.cs b/src/Web/DevHive.Web.Models/Rating/UpdateRatingWebModel.cs new file mode 100644 index 0000000..07ba0c3 --- /dev/null +++ b/src/Web/DevHive.Web.Models/Rating/UpdateRatingWebModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DevHive.Web.Models.Rating +{ + public class UpdateRatingWebModel + { + public Guid PostId { get; set; } + + public bool IsLike { get; set; } + } +} diff --git a/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs b/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs index aabee01..23c3eeb 100644 --- a/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs +++ b/src/Web/DevHive.Web/Configurations/Mapping/RatingMappings.cs @@ -11,6 +11,8 @@ namespace DevHive.Web.Configurations.Mapping CreateMap(); CreateMap(); + + CreateMap(); } } } diff --git a/src/Web/DevHive.Web/Controllers/RatingController.cs b/src/Web/DevHive.Web/Controllers/RatingController.cs index d2a7801..216dc27 100644 --- a/src/Web/DevHive.Web/Controllers/RatingController.cs +++ b/src/Web/DevHive.Web/Controllers/RatingController.cs @@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Mvc; namespace DevHive.Web.Controllers { [ApiController] + //[Authorize(Roles = "Admin,User")] [Route("api/[controller]")] public class RatingController { @@ -25,7 +26,6 @@ namespace DevHive.Web.Controllers } [HttpPost] - [Authorize(Roles = "Admin,User")] public async Task RatePost(Guid userId, [FromBody] CreateRatingWebModel createRatingWebModel, [FromHeader] string authorization) { CreateRatingServiceModel ratePostServiceModel = this._mapper.Map(createRatingWebModel); @@ -36,7 +36,7 @@ namespace DevHive.Web.Controllers if (Guid.Empty == id) return new BadRequestResult(); - return new OkObjectResult(id); + return new OkObjectResult(new { Id = id }); } [HttpGet] @@ -47,5 +47,23 @@ namespace DevHive.Web.Controllers return new OkObjectResult(readPostRatingWebModel); } + + [HttpPut] + public async Task UpdateRating(Guid userId, [FromBody] UpdateRatingWebModel updateRatingWebModel, [FromHeader] string authorization) + { + UpdateRatingServiceModel updateRatingServiceModel = + this._mapper.Map(updateRatingWebModel); + updateRatingServiceModel.UserId = userId; + + ReadRatingServiceModel readRatingServiceModel = await this._rateService.UpdateRating(updateRatingServiceModel); + + if (readRatingServiceModel == null) + return new BadRequestResult(); + else + { + ReadRatingWebModel readRatingWebModel = this._mapper.Map(readRatingServiceModel); + return new OkObjectResult(readRatingWebModel); + } + } } } -- cgit v1.2.3 From 83ae76a1b93c91cf7cfb5fc9ea1ef728ee47c839 Mon Sep 17 00:00:00 2001 From: transtrike Date: Sat, 27 Feb 2021 11:18:09 +0200 Subject: JWT Validations works; Introduced more bugs to fix later --- .../DevHive.Common.Models/DevHive.Common.csproj | 13 ---- .../DevHive.Common/Jwt/Interfaces/IJwtService.cs | 11 +++ src/Common/DevHive.Common/Jwt/JwtService.cs | 79 ++++++++++++++++++++++ src/DevHive.sln | 49 +++++++++----- .../DevHive.Services/Services/UserService.cs | 68 ++++++++++++------- .../Extensions/ConfigureDependencyInjection.cs | 12 +++- .../Controllers/ProfilePictureController.cs | 32 +++++++++ src/Web/DevHive.Web/Controllers/UserController.cs | 17 ----- src/Web/DevHive.Web/appsettings.json | 29 ++++---- 9 files changed, 225 insertions(+), 85 deletions(-) delete mode 100644 src/Common/DevHive.Common.Models/DevHive.Common.csproj create mode 100644 src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs create mode 100644 src/Common/DevHive.Common/Jwt/JwtService.cs create mode 100644 src/Web/DevHive.Web/Controllers/ProfilePictureController.cs (limited to 'src/Web/DevHive.Web/Configurations') diff --git a/src/Common/DevHive.Common.Models/DevHive.Common.csproj b/src/Common/DevHive.Common.Models/DevHive.Common.csproj deleted file mode 100644 index f6d662c..0000000 --- a/src/Common/DevHive.Common.Models/DevHive.Common.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - net5.0 - - - - - - - true - latest - - \ No newline at end of file diff --git a/src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs b/src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs new file mode 100644 index 0000000..d2f1756 --- /dev/null +++ b/src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; + +namespace DevHive.Common.Jwt.Interfaces +{ + public interface IJwtService + { + string GenerateJwtToken(Guid userId, string username, List roleNames); + bool ValidateToken(string authToken); + } +} diff --git a/src/Common/DevHive.Common/Jwt/JwtService.cs b/src/Common/DevHive.Common/Jwt/JwtService.cs new file mode 100644 index 0000000..677353a --- /dev/null +++ b/src/Common/DevHive.Common/Jwt/JwtService.cs @@ -0,0 +1,79 @@ +using System; +using System.Buffers.Text; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Security.Principal; +using System.Text; +using DevHive.Common.Jwt.Interfaces; +using Microsoft.IdentityModel.Tokens; + +namespace DevHive.Common.Jwt +{ + public class JwtService : IJwtService + { + private readonly string _validationIssuer; + private readonly string _audience; + private readonly byte[] _signingKey; + + public JwtService(byte[] signingKey, string validationIssuer, string audience) + { + this._signingKey = signingKey; + this._validationIssuer = validationIssuer; + this._audience = audience; + } + + public string GenerateJwtToken(Guid userId, string username, List roleNames) + { + var securityKey = new SymmetricSecurityKey(this._signingKey); + var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); + + HashSet claims = new() + { + new Claim("ID", $"{userId}"), + new Claim("Username", username) + }; + + foreach (var roleName in roleNames) + claims.Add(new Claim(ClaimTypes.Role, roleName)); + + SecurityTokenDescriptor securityTokenDescriptor = new() + { + Issuer = this._validationIssuer, + Audience = this._audience, + Subject = new ClaimsIdentity(claims), + Expires = DateTime.Today.AddDays(7), + SigningCredentials = credentials, + }; + + JwtSecurityTokenHandler tokenHandler = new(); + SecurityToken token = tokenHandler.CreateToken(securityTokenDescriptor); + + return tokenHandler.WriteToken(token); + } + + public bool ValidateToken(string authToken) + { + var tokenHandler = new JwtSecurityTokenHandler(); + var validationParameters = GetValidationParameters(); + + //Validate edge case where user can delete other users + + IPrincipal principal = tokenHandler.ValidateToken(authToken.Remove(0, 7), validationParameters, out _); + return principal.Identity.IsAuthenticated; + } + + private TokenValidationParameters GetValidationParameters() + { + return new TokenValidationParameters() + { + ValidateLifetime = true, + ValidateAudience = true, + ValidateIssuer = true, + ValidIssuer = this._validationIssuer, + ValidAudience = this._audience, + IssuerSigningKey = new SymmetricSecurityKey(this._signingKey) + }; + } + } +} diff --git a/src/DevHive.sln b/src/DevHive.sln index 05bdcda..a202180 100644 --- a/src/DevHive.sln +++ b/src/DevHive.sln @@ -11,10 +11,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevHive.Data.Models", "Data EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevHive.Data.Tests", "Data\DevHive.Data.Tests\DevHive.Data.Tests.csproj", "{F056B3F1-B72D-4935-87EA-F7BFEA96AFB0}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{F2864A9D-70F1-452F-AAAC-AAFD8102ABAD}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevHive.Common", "Common\DevHive.Common.Models\DevHive.Common.csproj", "{5C3DFE9B-9690-475E-A0AE-D62315D38337}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{7CA79114-C359-4871-BFA7-0EA898B50AE4}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevHive.Services", "Services\DevHive.Services\DevHive.Services.csproj", "{B5F22590-E3CE-4595-BE48-AA7F1797A6B8}" @@ -31,6 +27,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevHive.Web.Models", "Web\D EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevHive.Web.Tests", "Web\DevHive.Web.Tests\DevHive.Web.Tests.csproj", "{608273FF-01ED-48B3-B912-66CCDBF5572E}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{49B4EAF5-8F45-493F-A25A-7F37DAAE6B1E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevHive.Common", "Common\DevHive.Common\DevHive.Common.csproj", "{AAEC0516-A943-449E-A1E8-E0628BFFAA2E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevHive.Common.Models", "Common\DevHive.Common.Models\DevHive.Common.Models.csproj", "{3D63C965-A734-45D6-B75D-AFDCAB511293}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -80,18 +82,6 @@ Global {F056B3F1-B72D-4935-87EA-F7BFEA96AFB0}.Release|x64.Build.0 = Release|Any CPU {F056B3F1-B72D-4935-87EA-F7BFEA96AFB0}.Release|x86.ActiveCfg = Release|Any CPU {F056B3F1-B72D-4935-87EA-F7BFEA96AFB0}.Release|x86.Build.0 = Release|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Debug|x64.ActiveCfg = Debug|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Debug|x64.Build.0 = Debug|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Debug|x86.ActiveCfg = Debug|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Debug|x86.Build.0 = Debug|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Release|Any CPU.Build.0 = Release|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Release|x64.ActiveCfg = Release|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Release|x64.Build.0 = Release|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Release|x86.ActiveCfg = Release|Any CPU - {5C3DFE9B-9690-475E-A0AE-D62315D38337}.Release|x86.Build.0 = Release|Any CPU {B5F22590-E3CE-4595-BE48-AA7F1797A6B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B5F22590-E3CE-4595-BE48-AA7F1797A6B8}.Debug|Any CPU.Build.0 = Debug|Any CPU {B5F22590-E3CE-4595-BE48-AA7F1797A6B8}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -164,17 +154,42 @@ Global {608273FF-01ED-48B3-B912-66CCDBF5572E}.Release|x64.Build.0 = Release|Any CPU {608273FF-01ED-48B3-B912-66CCDBF5572E}.Release|x86.ActiveCfg = Release|Any CPU {608273FF-01ED-48B3-B912-66CCDBF5572E}.Release|x86.Build.0 = Release|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Debug|x64.ActiveCfg = Debug|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Debug|x64.Build.0 = Debug|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Debug|x86.ActiveCfg = Debug|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Debug|x86.Build.0 = Debug|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Release|Any CPU.Build.0 = Release|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Release|x64.ActiveCfg = Release|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Release|x64.Build.0 = Release|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Release|x86.ActiveCfg = Release|Any CPU + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E}.Release|x86.Build.0 = Release|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Debug|x64.ActiveCfg = Debug|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Debug|x64.Build.0 = Debug|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Debug|x86.ActiveCfg = Debug|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Debug|x86.Build.0 = Debug|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Release|Any CPU.Build.0 = Release|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Release|x64.ActiveCfg = Release|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Release|x64.Build.0 = Release|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Release|x86.ActiveCfg = Release|Any CPU + {3D63C965-A734-45D6-B75D-AFDCAB511293}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {70D0903D-C65F-4600-B6F8-F7BD00500A51} = {0C2AC7A9-AC68-4668-B88E-9370C596F498} {56F85916-3955-4558-8809-376D20902B94} = {0C2AC7A9-AC68-4668-B88E-9370C596F498} {F056B3F1-B72D-4935-87EA-F7BFEA96AFB0} = {0C2AC7A9-AC68-4668-B88E-9370C596F498} - {5C3DFE9B-9690-475E-A0AE-D62315D38337} = {F2864A9D-70F1-452F-AAAC-AAFD8102ABAD} {B5F22590-E3CE-4595-BE48-AA7F1797A6B8} = {7CA79114-C359-4871-BFA7-0EA898B50AE4} {2FFF985B-A26F-443D-A159-62ED2FD5A2BC} = {7CA79114-C359-4871-BFA7-0EA898B50AE4} {6E58003B-E5E8-4AA4-8F70-A9442BBFC110} = {7CA79114-C359-4871-BFA7-0EA898B50AE4} {A6D35BD9-A2A4-4937-89A8-DCB0D610B04A} = {768A592D-58EA-4CD3-A053-2E8F2DC7708A} {D8C898F7-A0DE-4939-8708-3D4A5C383EFC} = {768A592D-58EA-4CD3-A053-2E8F2DC7708A} {608273FF-01ED-48B3-B912-66CCDBF5572E} = {768A592D-58EA-4CD3-A053-2E8F2DC7708A} + {AAEC0516-A943-449E-A1E8-E0628BFFAA2E} = {49B4EAF5-8F45-493F-A25A-7F37DAAE6B1E} + {3D63C965-A734-45D6-B75D-AFDCAB511293} = {49B4EAF5-8F45-493F-A25A-7F37DAAE6B1E} EndGlobalSection EndGlobal diff --git a/src/Services/DevHive.Services/Services/UserService.cs b/src/Services/DevHive.Services/Services/UserService.cs index dfd45cc..cbcb116 100644 --- a/src/Services/DevHive.Services/Services/UserService.cs +++ b/src/Services/DevHive.Services/Services/UserService.cs @@ -13,9 +13,9 @@ using DevHive.Common.Models.Identity; using DevHive.Services.Interfaces; using DevHive.Data.Interfaces; using System.Linq; -using DevHive.Common.Models.Misc; using Microsoft.AspNetCore.Http; -using Newtonsoft.Json; +using DevHive.Common.Jwt; +using DevHive.Common.Jwt.Interfaces; namespace DevHive.Services.Services { @@ -28,6 +28,7 @@ namespace DevHive.Services.Services private readonly IMapper _userMapper; private readonly JwtOptions _jwtOptions; private readonly ICloudService _cloudService; + private readonly IJwtService _jwtService; public UserService(IUserRepository userRepository, ILanguageRepository languageRepository, @@ -35,7 +36,8 @@ namespace DevHive.Services.Services ITechnologyRepository technologyRepository, IMapper mapper, JwtOptions jwtOptions, - ICloudService cloudService) + ICloudService cloudService, + IJwtService jwtService) { this._userRepository = userRepository; this._roleRepository = roleRepository; @@ -44,6 +46,7 @@ namespace DevHive.Services.Services this._languageRepository = languageRepository; this._technologyRepository = technologyRepository; this._cloudService = cloudService; + this._jwtService = jwtService; } #region Authentication @@ -65,8 +68,10 @@ namespace DevHive.Services.Services } /// - /// Returns a new JSON Web Token (that can be used for authorization) for the given user + /// Register a user in the database and return a /// + /// Register model, containing registration information + /// A Token model, containing JWT Token for further verification public async Task RegisterUser(RegisterServiceModel registerModel) { if (await this._userRepository.DoesUsernameExistAsync(registerModel.UserName)) @@ -86,7 +91,12 @@ namespace DevHive.Services.Services throw new ArgumentException("Unable to add role to user"); User createdUser = await this._userRepository.GetByUsernameAsync(registerModel.UserName); - return new TokenModel(WriteJWTSecurityToken(createdUser.Id, createdUser.UserName, createdUser.Roles)); + List roleNames = createdUser + .Roles + .Select(x => x.Name) + .ToList(); + + return new TokenModel(this._jwtService.GenerateJwtToken(createdUser.Id, createdUser.UserName, roleNames)); } #endregion @@ -173,34 +183,38 @@ namespace DevHive.Services.Services /// is the same user as the one in the token (unless the user in the token has the admin role) /// and the roles in the token are the same as those in the user, gotten by the id in the token /// + /// + /// + /// public async Task ValidJWT(Guid id, string rawTokenData) { + return this._jwtService.ValidateToken(rawTokenData); // There is authorization name in the beginning, i.e. "Bearer eyJh..." - var jwt = new JwtSecurityTokenHandler().ReadJwtToken(rawTokenData.Remove(0, 7)); + // var jwt = new JwtSecurityTokenHandler().ReadJwtToken(rawTokenData.Remove(0, 7)); - Guid jwtUserID = new(UserService.GetClaimTypeValues("ID", jwt.Claims).First()); - List jwtRoleNames = UserService.GetClaimTypeValues("role", jwt.Claims); + // Guid jwtUserID = new(UserService.GetClaimTypeValues("ID", jwt.Claims).First()); + // List jwtRoleNames = UserService.GetClaimTypeValues("role", jwt.Claims); - User user = await this._userRepository.GetByIdAsync(jwtUserID) - ?? throw new ArgumentException("User does not exist!"); + // User user = await this._userRepository.GetByIdAsync(jwtUserID) + // ?? throw new ArgumentException("User does not exist!"); - /* Check if he is an admin */ - if (user.Roles.Any(x => x.Name == Role.AdminRole)) - return true; + // /* Check if he is an admin */ + // if (user.Roles.Any(x => x.Name == Role.AdminRole)) + // return true; - if (!jwtRoleNames.Contains(Role.AdminRole) && user.Id != id) - return false; + // if (!jwtRoleNames.Contains(Role.AdminRole) && user.Id != id) + // return false; - // Check if jwt contains all user roles (if it doesn't, jwt is either old or tampered with) - foreach (var role in user.Roles) - if (!jwtRoleNames.Contains(role.Name)) - return false; + // // Check if jwt contains all user roles (if it doesn't, jwt is either old or tampered with) + // foreach (var role in user.Roles) + // if (!jwtRoleNames.Contains(role.Name)) + // return false; - // Check if jwt contains only roles of user - if (jwtRoleNames.Count != user.Roles.Count) - return false; + // // Check if jwt contains only roles of user + // if (jwtRoleNames.Count != user.Roles.Count) + // return false; - return true; + // return true; } /// @@ -294,9 +308,13 @@ namespace DevHive.Services.Services user.Roles.Add(admin); await this._userRepository.EditAsync(user.Id, user); - User newUser = await this._userRepository.GetByIdAsync(userId); + User createdUser = await this._userRepository.GetByIdAsync(userId); + List roleNames = createdUser + .Roles + .Select(x => x.Name) + .ToList(); - return new TokenModel(WriteJWTSecurityToken(newUser.Id, newUser.UserName, newUser.Roles)); + return new TokenModel(this._jwtService.GenerateJwtToken(createdUser.Id, createdUser.UserName, roleNames)); } private async Task PopulateUserModel(User user, UpdateUserServiceModel updateUserServiceModel) diff --git a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs index c547951..660a416 100644 --- a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs +++ b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs @@ -1,3 +1,6 @@ +using System.Text; +using DevHive.Common.Jwt; +using DevHive.Common.Jwt.Interfaces; using DevHive.Data.Interfaces; using DevHive.Data.Repositories; using DevHive.Services.Interfaces; @@ -27,12 +30,19 @@ namespace DevHive.Web.Configurations.Extensions services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(options => new CloudinaryService( cloudName: configuration.GetSection("Cloud").GetSection("cloudName").Value, apiKey: configuration.GetSection("Cloud").GetSection("apiKey").Value, apiSecret: configuration.GetSection("Cloud").GetSection("apiSecret").Value)); - services.AddTransient(); + + services.AddSingleton(options => + new JwtService( + signingKey: Encoding.ASCII.GetBytes(configuration.GetSection("Jwt").GetSection("signingKey").Value), + validationIssuer: configuration.GetSection("Jwt").GetSection("validationIssuer").Value, + audience: configuration.GetSection("Jwt").GetSection("audience").Value)); } } } diff --git a/src/Web/DevHive.Web/Controllers/ProfilePictureController.cs b/src/Web/DevHive.Web/Controllers/ProfilePictureController.cs new file mode 100644 index 0000000..d3971ff --- /dev/null +++ b/src/Web/DevHive.Web/Controllers/ProfilePictureController.cs @@ -0,0 +1,32 @@ +using System; +using System.Threading.Tasks; +using DevHive.Services.Models.User; +using DevHive.Web.Models.User; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace DevHive.Web.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class ProfilePictureController + { + [HttpPut] + [Route("ProfilePicture")] + [Authorize(Roles = "User,Admin")] + public async Task UpdateProfilePicture(Guid userId, [FromForm] UpdateProfilePictureWebModel updateProfilePictureWebModel, [FromHeader] string authorization) + { + throw new NotImplementedException(); + // if (!await this._userService.ValidJWT(userId, authorization)) + // return new UnauthorizedResult(); + + // UpdateProfilePictureServiceModel updateProfilePictureServiceModel = this._userMapper.Map(updateProfilePictureWebModel); + // updateProfilePictureServiceModel.UserId = userId; + + // ProfilePictureServiceModel profilePictureServiceModel = await this._userService.UpdateProfilePicture(updateProfilePictureServiceModel); + // ProfilePictureWebModel profilePictureWebModel = this._userMapper.Map(profilePictureServiceModel); + + // return new AcceptedResult("UpdateProfilePicture", profilePictureWebModel); + } + } +} diff --git a/src/Web/DevHive.Web/Controllers/UserController.cs b/src/Web/DevHive.Web/Controllers/UserController.cs index 214fba7..a1e87f4 100644 --- a/src/Web/DevHive.Web/Controllers/UserController.cs +++ b/src/Web/DevHive.Web/Controllers/UserController.cs @@ -93,23 +93,6 @@ namespace DevHive.Web.Controllers return new AcceptedResult("UpdateUser", userWebModel); } - - [HttpPut] - [Route("ProfilePicture")] - [Authorize(Roles = "User,Admin")] - public async Task UpdateProfilePicture(Guid userId, [FromForm] UpdateProfilePictureWebModel updateProfilePictureWebModel, [FromHeader] string authorization) - { - if (!await this._userService.ValidJWT(userId, authorization)) - return new UnauthorizedResult(); - - UpdateProfilePictureServiceModel updateProfilePictureServiceModel = this._userMapper.Map(updateProfilePictureWebModel); - updateProfilePictureServiceModel.UserId = userId; - - ProfilePictureServiceModel profilePictureServiceModel = await this._userService.UpdateProfilePicture(updateProfilePictureServiceModel); - ProfilePictureWebModel profilePictureWebModel = this._userMapper.Map(profilePictureServiceModel); - - return new AcceptedResult("UpdateProfilePicture", profilePictureWebModel); - } #endregion #region Delete diff --git a/src/Web/DevHive.Web/appsettings.json b/src/Web/DevHive.Web/appsettings.json index bcdcae7..b7e0ce5 100644 --- a/src/Web/DevHive.Web/appsettings.json +++ b/src/Web/DevHive.Web/appsettings.json @@ -1,20 +1,25 @@ { - "AppSettings": { - "Secret": "gXfQlU6qpDleFWyimscjYcT3tgFsQg3yoFjcvSLxG56n1Vu2yptdIUq254wlJWjm" - }, - "ConnectionStrings": { - "DEV": "Server=localhost;Port=5432;Database=API;User Id=postgres;Password=;" + "AppSettings": { + "Secret": "" + }, + "Jwt": { + "signingKey": "", + "validationIssuer": "", + "audience": "" + }, + "ConnectionStrings": { + "DEV": "Server=localhost;Port=5432;Database=API;User Id=postgres;Password=;" }, "Cloud": { "cloudName": "devhive", "apiKey": "488664116365813", "apiSecret": "" }, - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - } + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } } -- cgit v1.2.3 From 2a85613d6827f5a1d151b856739863fbe9782143 Mon Sep 17 00:00:00 2001 From: transtrike Date: Sun, 28 Feb 2021 13:14:23 +0200 Subject: Removed JwtOptions --- src/Services/DevHive.Services/Options/JwtOptions.cs | 14 -------------- .../DevHive.Web/Configurations/Extensions/ConfigureJwt.cs | 14 ++++---------- src/Web/DevHive.Web/appsettings.json | 3 --- 3 files changed, 4 insertions(+), 27 deletions(-) delete mode 100644 src/Services/DevHive.Services/Options/JwtOptions.cs (limited to 'src/Web/DevHive.Web/Configurations') diff --git a/src/Services/DevHive.Services/Options/JwtOptions.cs b/src/Services/DevHive.Services/Options/JwtOptions.cs deleted file mode 100644 index d973f45..0000000 --- a/src/Services/DevHive.Services/Options/JwtOptions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Microsoft.Extensions.Options; - -namespace DevHive.Services.Options -{ - public class JwtOptions - { - public JwtOptions(string secret) - { - this.Secret = secret; - } - - public string Secret { get; init; } - } -} diff --git a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureJwt.cs b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureJwt.cs index 8d387bd..18127bc 100644 --- a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureJwt.cs +++ b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureJwt.cs @@ -1,6 +1,5 @@ using System.Text; using System.Threading.Tasks; -using DevHive.Services.Options; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -12,15 +11,10 @@ namespace DevHive.Web.Configurations.Extensions { public static void JWTConfiguration(this IServiceCollection services, IConfiguration configuration) { - services.AddSingleton(new JwtOptions(configuration - .GetSection("AppSettings") - .GetSection("Secret") - .Value)); - // Get key from appsettings.json - var key = Encoding.ASCII.GetBytes(configuration - .GetSection("AppSettings") - .GetSection("Secret") + var signingKey = Encoding.ASCII.GetBytes(configuration + .GetSection("Jwt") + .GetSection("signingKey") .Value); // Setup Jwt Authentication @@ -42,7 +36,7 @@ namespace DevHive.Web.Configurations.Extensions x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { - IssuerSigningKey = new SymmetricSecurityKey(key), + IssuerSigningKey = new SymmetricSecurityKey(signingKey), ValidateIssuer = false, ValidateAudience = false }; diff --git a/src/Web/DevHive.Web/appsettings.json b/src/Web/DevHive.Web/appsettings.json index b7e0ce5..fcf9805 100644 --- a/src/Web/DevHive.Web/appsettings.json +++ b/src/Web/DevHive.Web/appsettings.json @@ -1,7 +1,4 @@ { - "AppSettings": { - "Secret": "" - }, "Jwt": { "signingKey": "", "validationIssuer": "", -- cgit v1.2.3 From d0b2f33af25f6da7ceb85e836bc1e1f7bea8bb4d Mon Sep 17 00:00:00 2001 From: Danail Dimitrov Date: Sun, 28 Feb 2021 21:48:36 +0200 Subject: tryibg to fix rating layers --- .../Configurations/Mapping/RatingMappings.cs | 5 +- .../DevHive.Services/Interfaces/IRatingService.cs | 7 +- .../DevHive.Services/Services/RatingService.cs | 84 ++++------------------ .../Rating/CreateRatingWebModel.cs | 2 +- .../Extensions/ConfigureDependencyInjection.cs | 2 +- .../DevHive.Web/Controllers/RatingController.cs | 25 +++++-- 6 files changed, 42 insertions(+), 83 deletions(-) (limited to 'src/Web/DevHive.Web/Configurations') diff --git a/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs b/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs index 3ef7d33..4534511 100644 --- a/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs +++ b/src/Services/DevHive.Services/Configurations/Mapping/RatingMappings.cs @@ -8,7 +8,10 @@ namespace DevHive.Services.Configurations.Mapping { public RatingMappings() { - CreateMap(); + CreateMap() + .ForMember(dest => dest.User, src => src.Ignore()) + .ForMember(dest => dest.Post, src => src.Ignore()) + .ForMember(dest => dest.Id, src => src.Ignore()); CreateMap(); diff --git a/src/Services/DevHive.Services/Interfaces/IRatingService.cs b/src/Services/DevHive.Services/Interfaces/IRatingService.cs index b9ddc2c..beea821 100644 --- a/src/Services/DevHive.Services/Interfaces/IRatingService.cs +++ b/src/Services/DevHive.Services/Interfaces/IRatingService.cs @@ -10,14 +10,13 @@ namespace DevHive.Services.Interfaces Task RatePost(CreateRatingServiceModel createRatingServiceModel); Task GetRatingById(Guid ratingId); - Task HasUserRatedThisPost(Guid userId, Guid postId); + Task GetRatingByPostAndUser(Guid userId, Guid postId); + Task UpdateRating(UpdateRatingServiceModel updateRatingServiceModel); Task DeleteRating(Guid ratingId); - Task ValidateJwtForCreating(Guid userId, string rawTokenData); - - Task ValidateJwtForRating(Guid commentId, string rawTokenData); + Task HasUserRatedThisPost(Guid userId, Guid postId); } } diff --git a/src/Services/DevHive.Services/Services/RatingService.cs b/src/Services/DevHive.Services/Services/RatingService.cs index 22eeb99..6ddba1c 100644 --- a/src/Services/DevHive.Services/Services/RatingService.cs +++ b/src/Services/DevHive.Services/Services/RatingService.cs @@ -38,10 +38,8 @@ namespace DevHive.Services.Services Rating rating = this._mapper.Map(createRatingServiceModel); - User user = await this._userRepository.GetByIdAsync(createRatingServiceModel.UserId); - Post post = await this._postRepository.GetByIdAsync(createRatingServiceModel.PostId); - rating.User = user; - rating.Post = post; + rating.User = await this._userRepository.GetByIdAsync(createRatingServiceModel.UserId); + rating.Post = await this._postRepository.GetByIdAsync(createRatingServiceModel.PostId); bool success = await this._ratingRepository.AddAsync(rating); @@ -62,19 +60,21 @@ namespace DevHive.Services.Services Rating rating = await this._ratingRepository.GetByIdAsync(ratingId) ?? throw new ArgumentException("The rating does not exist"); - User user = await this._userRepository.GetByIdAsync(rating.User.Id) ?? - throw new ArgumentException("The user does not exist"); - ReadRatingServiceModel readRatingServiceModel = this._mapper.Map(rating); - readRatingServiceModel.UserId = user.Id; + readRatingServiceModel.UserId = rating.User.Id; return readRatingServiceModel; } - public async Task HasUserRatedThisPost(Guid userId, Guid postId) + public async Task GetRatingByPostAndUser(Guid userId, Guid postId) { - return await this._ratingRepository - .UserRatedPost(userId, postId); + Rating rating = await this._ratingRepository.GetRatingByUserAndPostId(userId, postId) ?? + throw new ArgumentException("The rating does not exist"); + + ReadRatingServiceModel readRatingServiceModel = this._mapper.Map(rating); + readRatingServiceModel.UserId = rating.User.Id; + + return readRatingServiceModel; } #endregion @@ -116,66 +116,10 @@ namespace DevHive.Services.Services } #endregion - #region Validations - /// - /// Checks whether the user Id in the token and the given user Id match - /// - public async Task ValidateJwtForCreating(Guid userId, string rawTokenData) - { - User user = await this.GetUserForValidation(rawTokenData); - - return user.Id == userId; - } - - /// - /// Checks whether the comment, gotten with the commentId, - /// is made by the user in the token - /// or if the user in the token is an admin - /// - public async Task ValidateJwtForRating(Guid commentId, string rawTokenData) - { - Rating rating = await this._ratingRepository.GetByIdAsync(commentId) ?? - throw new ArgumentException("Rating does not exist!"); - User user = await this.GetUserForValidation(rawTokenData); - - //If user made the comment - if (rating.User.Id == user.Id) - return true; - //If user is admin - else if (user.Roles.Any(x => x.Name == Role.AdminRole)) - return true; - else - return false; - } - - /// - /// Returns the user, via their Id in the token - /// - private async Task GetUserForValidation(string rawTokenData) - { - JwtSecurityToken jwt = new JwtSecurityTokenHandler().ReadJwtToken(rawTokenData.Remove(0, 7)); - - Guid jwtUserId = Guid.Parse(this.GetClaimTypeValues("ID", jwt.Claims).First()); - - User user = await this._userRepository.GetByIdAsync(jwtUserId) ?? - throw new ArgumentException("User does not exist!"); - - return user; - } - - /// - /// Returns all values from a given claim type - /// - private List GetClaimTypeValues(string type, IEnumerable claims) + public async Task HasUserRatedThisPost(Guid userId, Guid postId) { - List toReturn = new(); - - foreach (var claim in claims) - if (claim.Type == type) - toReturn.Add(claim.Value); - - return toReturn; + return await this._ratingRepository + .UserRatedPost(userId, postId); } - #endregion } } diff --git a/src/Web/DevHive.Web.Models/Rating/CreateRatingWebModel.cs b/src/Web/DevHive.Web.Models/Rating/CreateRatingWebModel.cs index 010e04e..abbb702 100644 --- a/src/Web/DevHive.Web.Models/Rating/CreateRatingWebModel.cs +++ b/src/Web/DevHive.Web.Models/Rating/CreateRatingWebModel.cs @@ -6,6 +6,6 @@ namespace DevHive.Web.Models.Rating { public Guid PostId { get; set; } - public bool IsLiked { get; set; } + public bool IsLike { get; set; } } } diff --git a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs index 6a5799f..a0d0979 100644 --- a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs +++ b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureDependencyInjection.cs @@ -30,7 +30,7 @@ namespace DevHive.Web.Configurations.Extensions services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); + services.AddTransient(); services.AddTransient(options => new CloudinaryService( diff --git a/src/Web/DevHive.Web/Controllers/RatingController.cs b/src/Web/DevHive.Web/Controllers/RatingController.cs index 344acb2..5716b85 100644 --- a/src/Web/DevHive.Web/Controllers/RatingController.cs +++ b/src/Web/DevHive.Web/Controllers/RatingController.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using AutoMapper; +using DevHive.Common.Jwt.Interfaces; using DevHive.Services.Interfaces; using DevHive.Services.Models.Post.Rating; using DevHive.Web.Models.Rating; @@ -17,18 +18,20 @@ namespace DevHive.Web.Controllers private readonly IRatingService _rateService; private readonly IUserService _userService; private readonly IMapper _mapper; + private readonly IJwtService _jwtService; - public RatingController(IRatingService rateService, IUserService userService, IMapper mapper) + public RatingController(IRatingService rateService, IUserService userService, IMapper mapper, IJwtService jwtService) { this._rateService = rateService; this._userService = userService; this._mapper = mapper; + this._jwtService = jwtService; } [HttpPost] public async Task RatePost(Guid userId, [FromBody] CreateRatingWebModel createRatingWebModel, [FromHeader] string authorization) { - if (!await this._rateService.ValidateJwtForCreating(userId, authorization)) + if (!this._jwtService.ValidateToken(userId, authorization)) return new UnauthorizedResult(); CreateRatingServiceModel ratePostServiceModel = this._mapper.Map(createRatingWebModel); @@ -51,10 +54,20 @@ namespace DevHive.Web.Controllers return new OkObjectResult(readPostRatingWebModel); } + [HttpGet] + [Route("GetByUserAndPost")] + public async Task GetRatingByUserAndPost(Guid userId, Guid postId) + { + ReadRatingServiceModel readRatingServiceModel = await this._rateService.GetRatingByPostAndUser(userId, postId); + ReadRatingWebModel readPostRatingWebModel = this._mapper.Map(readRatingServiceModel); + + return new OkObjectResult(readPostRatingWebModel); + } + [HttpPut] public async Task UpdateRating(Guid userId, [FromBody] UpdateRatingWebModel updateRatingWebModel, [FromHeader] string authorization) { - if (!await this._rateService.ValidateJwtForRating(updateRatingWebModel.Id, authorization)) + if (!this._jwtService.ValidateToken(userId, authorization)) return new UnauthorizedResult(); UpdateRatingServiceModel updateRatingServiceModel = @@ -73,12 +86,12 @@ namespace DevHive.Web.Controllers } [HttpDelete] - public async Task DeleteTating(Guid id, [FromHeader] string authorization) + public async Task DeleteTating(Guid userId, Guid ratingId, [FromHeader] string authorization) { - if (!await this._rateService.ValidateJwtForRating(id, authorization)) + if (!this._jwtService.ValidateToken(userId, authorization)) return new UnauthorizedResult(); - return await this._rateService.DeleteRating(id) ? + return await this._rateService.DeleteRating(ratingId) ? new OkResult() : new BadRequestObjectResult("Could not delete Rating"); } -- cgit v1.2.3 From 804d274223734ea1c67920622ceb453cca602fc9 Mon Sep 17 00:00:00 2001 From: transtrike Date: Mon, 1 Mar 2021 08:45:55 +0200 Subject: Fixed AutoMapper Assembly Error --- src/Web/DevHive.Web/Configurations/Extensions/ConfigureAutoMapper.cs | 3 +++ src/Web/DevHive.Web/Startup.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/Web/DevHive.Web/Configurations') diff --git a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureAutoMapper.cs b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureAutoMapper.cs index 0b8194e..cd5679f 100644 --- a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureAutoMapper.cs +++ b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureAutoMapper.cs @@ -1,4 +1,7 @@ using System; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; using AutoMapper; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; diff --git a/src/Web/DevHive.Web/Startup.cs b/src/Web/DevHive.Web/Startup.cs index dbcf131..40f674d 100644 --- a/src/Web/DevHive.Web/Startup.cs +++ b/src/Web/DevHive.Web/Startup.cs @@ -29,11 +29,11 @@ namespace DevHive.Web x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; }); + services.DependencyInjectionConfiguration(this.Configuration); services.DatabaseConfiguration(Configuration); services.SwaggerConfiguration(); services.JWTConfiguration(Configuration); services.AutoMapperConfiguration(); - services.DependencyInjectionConfiguration(this.Configuration); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. -- cgit v1.2.3 From b9a9d63418d728560b17c23d49255328d16ccb11 Mon Sep 17 00:00:00 2001 From: transtrike Date: Wed, 3 Mar 2021 18:35:12 +0200 Subject: NSwag replaced Swagger; Doc prep configured --- .../DevHive.Common.Models.csproj | 2 +- .../DevHive.Data.Models/DevHive.Data.Models.csproj | 2 +- .../DevHive.Data.Tests/DevHive.Data.Tests.csproj | 2 +- src/Data/DevHive.Data/DevHive.Data.csproj | 2 +- .../DevHive.Services.Models.csproj | 10 ++-- .../DevHive.Services.Tests.csproj | 20 ++++---- .../DevHive.Services/DevHive.Services.csproj | 22 ++++----- .../DevHive.Web.Models/DevHive.Web.Models.csproj | 10 ++-- src/Web/DevHive.Web.Tests/DevHive.Web.Tests.csproj | 18 +++---- .../Configurations/Extensions/ConfigureSwagger.cs | 56 +++++++++++++--------- src/Web/DevHive.Web/DevHive.Web.csproj | 37 +++++++------- src/Web/DevHive.Web/Startup.cs | 2 +- 12 files changed, 97 insertions(+), 86 deletions(-) (limited to 'src/Web/DevHive.Web/Configurations') diff --git a/src/Common/DevHive.Common.Models/DevHive.Common.Models.csproj b/src/Common/DevHive.Common.Models/DevHive.Common.Models.csproj index f6d662c..a952c59 100644 --- a/src/Common/DevHive.Common.Models/DevHive.Common.Models.csproj +++ b/src/Common/DevHive.Common.Models/DevHive.Common.Models.csproj @@ -4,7 +4,7 @@ - + true diff --git a/src/Data/DevHive.Data.Models/DevHive.Data.Models.csproj b/src/Data/DevHive.Data.Models/DevHive.Data.Models.csproj index e9dc644..d249c77 100644 --- a/src/Data/DevHive.Data.Models/DevHive.Data.Models.csproj +++ b/src/Data/DevHive.Data.Models/DevHive.Data.Models.csproj @@ -5,6 +5,6 @@ - + \ No newline at end of file diff --git a/src/Data/DevHive.Data.Tests/DevHive.Data.Tests.csproj b/src/Data/DevHive.Data.Tests/DevHive.Data.Tests.csproj index 46c7b83..25b2b39 100644 --- a/src/Data/DevHive.Data.Tests/DevHive.Data.Tests.csproj +++ b/src/Data/DevHive.Data.Tests/DevHive.Data.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/Data/DevHive.Data/DevHive.Data.csproj b/src/Data/DevHive.Data/DevHive.Data.csproj index 46928c6..fcdb7ae 100644 --- a/src/Data/DevHive.Data/DevHive.Data.csproj +++ b/src/Data/DevHive.Data/DevHive.Data.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/Services/DevHive.Services.Models/DevHive.Services.Models.csproj b/src/Services/DevHive.Services.Models/DevHive.Services.Models.csproj index 6bbc60e..a55972a 100644 --- a/src/Services/DevHive.Services.Models/DevHive.Services.Models.csproj +++ b/src/Services/DevHive.Services.Models/DevHive.Services.Models.csproj @@ -3,11 +3,11 @@ net5.0 - - + + - - + + - + \ No newline at end of file diff --git a/src/Services/DevHive.Services.Tests/DevHive.Services.Tests.csproj b/src/Services/DevHive.Services.Tests/DevHive.Services.Tests.csproj index b3d0a32..d85eea2 100644 --- a/src/Services/DevHive.Services.Tests/DevHive.Services.Tests.csproj +++ b/src/Services/DevHive.Services.Tests/DevHive.Services.Tests.csproj @@ -4,20 +4,20 @@ false - - - - - - + + + + + + - - - + + + true latest - + \ No newline at end of file diff --git a/src/Services/DevHive.Services/DevHive.Services.csproj b/src/Services/DevHive.Services/DevHive.Services.csproj index 55d9d4e..f51c1b6 100644 --- a/src/Services/DevHive.Services/DevHive.Services.csproj +++ b/src/Services/DevHive.Services/DevHive.Services.csproj @@ -3,25 +3,25 @@ net5.0 - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - - + + + + + - - - - + + + + true latest - + \ No newline at end of file diff --git a/src/Web/DevHive.Web.Models/DevHive.Web.Models.csproj b/src/Web/DevHive.Web.Models/DevHive.Web.Models.csproj index 7f3f577..9d62eee 100644 --- a/src/Web/DevHive.Web.Models/DevHive.Web.Models.csproj +++ b/src/Web/DevHive.Web.Models/DevHive.Web.Models.csproj @@ -3,11 +3,11 @@ net5.0 - - + + - - + + - + \ No newline at end of file diff --git a/src/Web/DevHive.Web.Tests/DevHive.Web.Tests.csproj b/src/Web/DevHive.Web.Tests/DevHive.Web.Tests.csproj index 41afbd4..5099119 100644 --- a/src/Web/DevHive.Web.Tests/DevHive.Web.Tests.csproj +++ b/src/Web/DevHive.Web.Tests/DevHive.Web.Tests.csproj @@ -4,19 +4,19 @@ false - - - - - + + + + + - - - + + + true latest - + \ No newline at end of file diff --git a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureSwagger.cs b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureSwagger.cs index bfa44b0..9387561 100644 --- a/src/Web/DevHive.Web/Configurations/Extensions/ConfigureSwagger.cs +++ b/src/Web/DevHive.Web/Configurations/Extensions/ConfigureSwagger.cs @@ -1,12 +1,8 @@ -using System; -using System.IO; using System.Linq; -using System.Reflection; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; -using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using NSwag; +using NSwag.Generation.Processors.Security; namespace DevHive.Web.Configurations.Extensions { @@ -20,33 +16,49 @@ namespace DevHive.Web.Configurations.Extensions public static void SwaggerConfiguration(this IServiceCollection services) { - services.AddSwaggerGen(c => + services.AddOpenApiDocument(c => { - c.SwaggerDoc("v0.1", new OpenApiInfo + c.GenerateXmlObjects = true; + c.UseControllerSummaryAsTagDescription = true; + + c.AllowNullableBodyParameters = false; + c.Description = "DevHive Social Media's API Endpoints"; + + c.PostProcess = doc => { - Version = "v0.1", - Title = "API", - Description = "DevHive Social Media's first official API release", - TermsOfService = new Uri(TermsOfServiceUri), - License = new OpenApiLicense + doc.Info.Version = "v0.1"; + doc.Info.Title = "API"; + doc.Info.Description = "DevHive Social Media's first official API release"; + doc.Info.TermsOfService = TermsOfServiceUri; + doc.Info.License = new NSwag.OpenApiLicense { Name = LicenseName, - Url = new Uri(LicenseUri) - } - }); + Url = LicenseUri + }; + }; - string xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; - string xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); - c.IncludeXmlComments(xmlPath); + c.AddSecurity("Bearer", Enumerable.Empty(), new OpenApiSecurityScheme + { + Type = OpenApiSecuritySchemeType.ApiKey, + Name = "Authorization", + In = OpenApiSecurityApiKeyLocation.Header, + Description = "Type into the textbox: Bearer {your JWT token}." + }); + c.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("Bearer")); }); } public static void UseSwaggerConfiguration(this IApplicationBuilder app) { - app.UseSwagger(); - app.UseSwaggerUI(c => + app.UseOpenApi(c => + { + c.DocumentName = "v0.1"; + }); + app.UseSwaggerUi3(c => { - c.SwaggerEndpoint("/swagger/v0.1/swagger.json", "v0.1"); + c.DocumentTitle = "DevHive API"; + c.EnableTryItOut = false; + c.DocExpansion = "list"; }); } } diff --git a/src/Web/DevHive.Web/DevHive.Web.csproj b/src/Web/DevHive.Web/DevHive.Web.csproj index ea9eee6..38f21e6 100644 --- a/src/Web/DevHive.Web/DevHive.Web.csproj +++ b/src/Web/DevHive.Web/DevHive.Web.csproj @@ -5,32 +5,31 @@ true latest - true - true + true + true - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - - - - - - - - + + + + + + + + + + - - - - + + + + diff --git a/src/Web/DevHive.Web/Startup.cs b/src/Web/DevHive.Web/Startup.cs index 40f674d..ebd091e 100644 --- a/src/Web/DevHive.Web/Startup.cs +++ b/src/Web/DevHive.Web/Startup.cs @@ -48,7 +48,6 @@ namespace DevHive.Web if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); - app.UseSwaggerConfiguration(); } else { @@ -56,6 +55,7 @@ namespace DevHive.Web app.UseExceptionHandlerMiddlewareConfiguration(); } + app.UseSwaggerConfiguration(); app.UseDatabaseConfiguration(); app.UseAutoMapperConfiguration(); -- cgit v1.2.3