diff options
14 files changed, 1415 insertions, 208 deletions
diff --git a/src/DevHive.Data/DevHiveContext.cs b/src/DevHive.Data/DevHiveContext.cs index 0b81f92..9de33c3 100644 --- a/src/DevHive.Data/DevHiveContext.cs +++ b/src/DevHive.Data/DevHiveContext.cs @@ -16,7 +16,6 @@ namespace DevHive.Data public DbSet<Post> Posts { get; set; } public DbSet<PostAttachments> PostAttachments { get; set; } public DbSet<Comment> Comments { get; set; } - public DbSet<UserFriend> UserFriends { get; set; } public DbSet<Rating> Rating { get; set; } public DbSet<RatedPost> RatedPost { get; set; } public DbSet<UserRate> UserRate { get; set; } @@ -38,20 +37,6 @@ namespace DevHive.Data .HasMany(x => x.Roles) .WithMany(x => x.Users); - /* Friends */ - builder.Entity<UserFriend>() - .HasKey(x => new { x.UserId, x.FriendId }); - - builder.Entity<UserFriend>() - .HasOne(x => x.User) - .WithMany(x => x.MyFriends) - .HasForeignKey(x => x.UserId); - - builder.Entity<UserFriend>() - .HasOne(x => x.Friend) - .WithMany(x => x.FriendsOf) - .HasForeignKey(x => x.FriendId); - /* Languages */ builder.Entity<User>() .HasMany(x => x.Languages) diff --git a/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs b/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs index 5b6ab9e..5ebe3d3 100644 --- a/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs +++ b/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs @@ -10,14 +10,13 @@ namespace DevHive.Data.Interfaces.Repositories { //Read Task<User> GetByUsernameAsync(string username); - IEnumerable<User> QueryAll(); Task<bool> UpdateProfilePicture(Guid userId, string pictureUrl); //Validations + Task<bool> ValidateFriendsCollectionAsync(List<string> usernames); Task<bool> DoesEmailExistAsync(string email); Task<bool> DoesUserExistAsync(Guid id); - Task<bool> DoesUserHaveThisFriendAsync(Guid userId, Guid friendId); - bool DoesUserHaveThisUsername(Guid id, string username); Task<bool> DoesUsernameExistAsync(string username); + bool DoesUserHaveThisUsername(Guid id, string username); } } diff --git a/src/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.Designer.cs b/src/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.Designer.cs new file mode 100644 index 0000000..c11374a --- /dev/null +++ b/src/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.Designer.cs @@ -0,0 +1,643 @@ +// <auto-generated /> +using System; +using System.Collections.Generic; +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("20210205150447_Friends_Init_Config")] + partial class Friends_Init_Config + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseIdentityByDefaultColumns() + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.1"); + + modelBuilder.Entity("DevHive.Data.Models.Comment", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<Guid?>("CreatorId") + .HasColumnType("uuid"); + + b.Property<string>("Message") + .HasColumnType("text"); + + b.Property<Guid?>("PostId") + .HasColumnType("uuid"); + + b.Property<DateTime>("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<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<string>("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Languages"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<Guid?>("CreatorId") + .HasColumnType("uuid"); + + b.Property<List<string>>("FileUrls") + .HasColumnType("text[]"); + + b.Property<string>("Message") + .HasColumnType("text"); + + b.Property<DateTime>("TimeCreated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<string>("PictureURL") + .HasColumnType("text"); + + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("ProfilePicture"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Rating", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<int>("Rate") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Rating"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Role", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<string>("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property<string>("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property<string>("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<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<string>("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Technologies"); + }); + + modelBuilder.Entity("DevHive.Data.Models.User", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<int>("AccessFailedCount") + .HasColumnType("integer"); + + b.Property<string>("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property<string>("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property<bool>("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property<string>("FirstName") + .HasColumnType("text"); + + b.Property<string>("LastName") + .HasColumnType("text"); + + b.Property<bool>("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property<DateTimeOffset?>("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property<string>("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property<string>("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property<string>("PasswordHash") + .HasColumnType("text"); + + b.Property<string>("PhoneNumber") + .HasColumnType("text"); + + b.Property<bool>("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property<string>("SecurityStamp") + .HasColumnType("text"); + + b.Property<bool>("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property<Guid?>("UserId") + .HasColumnType("uuid"); + + b.Property<string>("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("DevHive.Data.RelationModels.RatedPost", b => + { + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.Property<Guid>("PostId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "PostId"); + + b.HasIndex("PostId"); + + b.ToTable("RatedPosts"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b => + { + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.Property<Guid>("FriendId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "FriendId"); + + b.HasIndex("FriendId"); + + b.ToTable("UserFriends"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<bool>("Rate") + .HasColumnType("boolean"); + + b.Property<Guid?>("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserRates"); + }); + + modelBuilder.Entity("LanguageUser", b => + { + b.Property<Guid>("LanguagesId") + .HasColumnType("uuid"); + + b.Property<Guid>("UsersId") + .HasColumnType("uuid"); + + b.HasKey("LanguagesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("LanguageUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .UseIdentityByDefaultColumn(); + + b.Property<string>("ClaimType") + .HasColumnType("text"); + + b.Property<string>("ClaimValue") + .HasColumnType("text"); + + b.Property<Guid>("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .UseIdentityByDefaultColumn(); + + b.Property<string>("ClaimType") + .HasColumnType("text"); + + b.Property<string>("ClaimValue") + .HasColumnType("text"); + + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b => + { + b.Property<string>("LoginProvider") + .HasColumnType("text"); + + b.Property<string>("ProviderKey") + .HasColumnType("text"); + + b.Property<string>("ProviderDisplayName") + .HasColumnType("text"); + + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b => + { + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.Property<Guid>("RoleId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b => + { + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.Property<string>("LoginProvider") + .HasColumnType("text"); + + b.Property<string>("Name") + .HasColumnType("text"); + + b.Property<string>("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.Property<Guid>("RolesId") + .HasColumnType("uuid"); + + b.Property<Guid>("UsersId") + .HasColumnType("uuid"); + + b.HasKey("RolesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("RoleUser"); + }); + + modelBuilder.Entity("TechnologyUser", b => + { + b.Property<Guid>("TechnologiesId") + .HasColumnType("uuid"); + + b.Property<Guid>("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.User", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany("Friends") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b => + { + b.HasOne("DevHive.Data.Models.Post", "Post") + .WithMany() + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Post"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b => + { + b.HasOne("DevHive.Data.Models.User", "Friend") + .WithMany() + .HasForeignKey("FriendId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Friend"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b => + { + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + 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<System.Guid>", b => + { + b.HasOne("DevHive.Data.Models.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", 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<System.Guid>", 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("Comments"); + }); + + modelBuilder.Entity("DevHive.Data.Models.User", b => + { + b.Navigation("Comments"); + + b.Navigation("Friends"); + + b.Navigation("Posts"); + + b.Navigation("ProfilePicture"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.cs b/src/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.cs new file mode 100644 index 0000000..1fc970d --- /dev/null +++ b/src/DevHive.Data/Migrations/20210205150447_Friends_Init_Config.cs @@ -0,0 +1,45 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace DevHive.Data.Migrations +{ + public partial class Friends_Init_Config : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn<Guid>( + name: "UserId", + table: "AspNetUsers", + type: "uuid", + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUsers_UserId", + table: "AspNetUsers", + column: "UserId"); + + migrationBuilder.AddForeignKey( + name: "FK_AspNetUsers_AspNetUsers_UserId", + table: "AspNetUsers", + column: "UserId", + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AspNetUsers_AspNetUsers_UserId", + table: "AspNetUsers"); + + migrationBuilder.DropIndex( + name: "IX_AspNetUsers_UserId", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "UserId", + table: "AspNetUsers"); + } + } +} diff --git a/src/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.Designer.cs b/src/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.Designer.cs new file mode 100644 index 0000000..3ad3ec8 --- /dev/null +++ b/src/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.Designer.cs @@ -0,0 +1,609 @@ +// <auto-generated /> +using System; +using System.Collections.Generic; +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("20210205160520_Friends_First_Tweek")] + partial class Friends_First_Tweek + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseIdentityByDefaultColumns() + .HasAnnotation("Relational:MaxIdentifierLength", 63) + .HasAnnotation("ProductVersion", "5.0.1"); + + modelBuilder.Entity("DevHive.Data.Models.Comment", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<Guid?>("CreatorId") + .HasColumnType("uuid"); + + b.Property<string>("Message") + .HasColumnType("text"); + + b.Property<Guid?>("PostId") + .HasColumnType("uuid"); + + b.Property<DateTime>("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<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<string>("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Languages"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<Guid?>("CreatorId") + .HasColumnType("uuid"); + + b.Property<List<string>>("FileUrls") + .HasColumnType("text[]"); + + b.Property<string>("Message") + .HasColumnType("text"); + + b.Property<DateTime>("TimeCreated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("DevHive.Data.Models.ProfilePicture", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<string>("PictureURL") + .HasColumnType("text"); + + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("ProfilePicture"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Rating", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<int>("Rate") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Rating"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Role", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<string>("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property<string>("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property<string>("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<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<string>("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Technologies"); + }); + + modelBuilder.Entity("DevHive.Data.Models.User", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<int>("AccessFailedCount") + .HasColumnType("integer"); + + b.Property<string>("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property<string>("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property<bool>("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property<string>("FirstName") + .HasColumnType("text"); + + b.Property<string>("LastName") + .HasColumnType("text"); + + b.Property<bool>("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property<DateTimeOffset?>("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property<string>("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property<string>("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property<string>("PasswordHash") + .HasColumnType("text"); + + b.Property<string>("PhoneNumber") + .HasColumnType("text"); + + b.Property<bool>("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property<string>("SecurityStamp") + .HasColumnType("text"); + + b.Property<bool>("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property<Guid?>("UserId") + .HasColumnType("uuid"); + + b.Property<string>("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("DevHive.Data.RelationModels.RatedPost", b => + { + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.Property<Guid>("PostId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "PostId"); + + b.HasIndex("PostId"); + + b.ToTable("RatedPosts"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property<bool>("Rate") + .HasColumnType("boolean"); + + b.Property<Guid?>("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserRates"); + }); + + modelBuilder.Entity("LanguageUser", b => + { + b.Property<Guid>("LanguagesId") + .HasColumnType("uuid"); + + b.Property<Guid>("UsersId") + .HasColumnType("uuid"); + + b.HasKey("LanguagesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("LanguageUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .UseIdentityByDefaultColumn(); + + b.Property<string>("ClaimType") + .HasColumnType("text"); + + b.Property<string>("ClaimValue") + .HasColumnType("text"); + + b.Property<Guid>("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .UseIdentityByDefaultColumn(); + + b.Property<string>("ClaimType") + .HasColumnType("text"); + + b.Property<string>("ClaimValue") + .HasColumnType("text"); + + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b => + { + b.Property<string>("LoginProvider") + .HasColumnType("text"); + + b.Property<string>("ProviderKey") + .HasColumnType("text"); + + b.Property<string>("ProviderDisplayName") + .HasColumnType("text"); + + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b => + { + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.Property<Guid>("RoleId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b => + { + b.Property<Guid>("UserId") + .HasColumnType("uuid"); + + b.Property<string>("LoginProvider") + .HasColumnType("text"); + + b.Property<string>("Name") + .HasColumnType("text"); + + b.Property<string>("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("RoleUser", b => + { + b.Property<Guid>("RolesId") + .HasColumnType("uuid"); + + b.Property<Guid>("UsersId") + .HasColumnType("uuid"); + + b.HasKey("RolesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("RoleUser"); + }); + + modelBuilder.Entity("TechnologyUser", b => + { + b.Property<Guid>("TechnologiesId") + .HasColumnType("uuid"); + + b.Property<Guid>("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.User", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany("Friends") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.RatedPost", b => + { + b.HasOne("DevHive.Data.Models.Post", "Post") + .WithMany() + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Post"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b => + { + b.HasOne("DevHive.Data.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + 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<System.Guid>", b => + { + b.HasOne("DevHive.Data.Models.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b => + { + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", 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<System.Guid>", 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("Comments"); + }); + + modelBuilder.Entity("DevHive.Data.Models.User", b => + { + b.Navigation("Comments"); + + b.Navigation("Friends"); + + b.Navigation("Posts"); + + b.Navigation("ProfilePicture"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.cs b/src/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.cs new file mode 100644 index 0000000..565f863 --- /dev/null +++ b/src/DevHive.Data/Migrations/20210205160520_Friends_First_Tweek.cs @@ -0,0 +1,46 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace DevHive.Data.Migrations +{ + public partial class Friends_First_Tweek : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "UserFriends"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "UserFriends", + columns: table => new + { + UserId = table.Column<Guid>(type: "uuid", nullable: false), + FriendId = table.Column<Guid>(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserFriends", x => new { x.UserId, x.FriendId }); + table.ForeignKey( + name: "FK_UserFriends_AspNetUsers_FriendId", + column: x => x.FriendId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_UserFriends_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_UserFriends_FriendId", + table: "UserFriends", + column: "FriendId"); + } + } +} diff --git a/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs b/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs index 6e0a03a..dc5739c 100644 --- a/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs +++ b/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs @@ -218,6 +218,9 @@ namespace DevHive.Data.Migrations b.Property<bool>("TwoFactorEnabled") .HasColumnType("boolean"); + b.Property<Guid?>("UserId") + .HasColumnType("uuid"); + b.Property<string>("UserName") .HasMaxLength(256) .HasColumnType("character varying(256)"); @@ -231,6 +234,8 @@ namespace DevHive.Data.Migrations .IsUnique() .HasDatabaseName("UserNameIndex"); + b.HasIndex("UserId"); + b.HasIndex("UserName") .IsUnique(); @@ -271,21 +276,6 @@ namespace DevHive.Data.Migrations b.ToTable("RatedPosts"); }); - modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b => - { - b.Property<Guid>("UserId") - .HasColumnType("uuid"); - - b.Property<Guid>("FriendId") - .HasColumnType("uuid"); - - b.HasKey("UserId", "FriendId"); - - b.HasIndex("FriendId"); - - b.ToTable("UserFriends"); - }); - modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b => { b.Property<Guid>("Id") @@ -530,25 +520,6 @@ namespace DevHive.Data.Migrations b.Navigation("User"); }); - modelBuilder.Entity("DevHive.Data.RelationModels.UserFriend", b => - { - b.HasOne("DevHive.Data.Models.User", "Friend") - .WithMany("FriendsOf") - .HasForeignKey("FriendId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("DevHive.Data.Models.User", "User") - .WithMany("MyFriends") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Friend"); - - b.Navigation("User"); - }); - modelBuilder.Entity("DevHive.Data.RelationModels.UserRate", b => { b.HasOne("DevHive.Data.Models.Post", "Post") @@ -673,9 +644,7 @@ namespace DevHive.Data.Migrations { b.Navigation("Comments"); - b.Navigation("FriendsOf"); - - b.Navigation("MyFriends"); + b.Navigation("Friends"); b.Navigation("Posts"); diff --git a/src/DevHive.Data/Models/User.cs b/src/DevHive.Data/Models/User.cs index f666677..983d073 100644 --- a/src/DevHive.Data/Models/User.cs +++ b/src/DevHive.Data/Models/User.cs @@ -24,9 +24,7 @@ namespace DevHive.Data.Models public HashSet<Post> Posts { get; set; } = new(); - public HashSet<UserFriend> MyFriends { get; set; } = new(); - - public HashSet<UserFriend> FriendsOf { get; set; } = new(); + public HashSet<User> Friends { get; set; } = new(); public HashSet<Comment> Comments { get; set; } = new(); diff --git a/src/DevHive.Data/RelationModels/UserFriend.cs b/src/DevHive.Data/RelationModels/UserFriend.cs deleted file mode 100644 index 32a00d4..0000000 --- a/src/DevHive.Data/RelationModels/UserFriend.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using DevHive.Data.Models; - -namespace DevHive.Data.RelationModels -{ - [Table("UserFriends")] - public class UserFriend - { - public Guid UserId { get; set; } - public User User { get; set; } - - public Guid FriendId { get; set; } - public User Friend { get; set; } - } -} diff --git a/src/DevHive.Data/Repositories/UserRepository.cs b/src/DevHive.Data/Repositories/UserRepository.cs index ed8db49..6e97e60 100644 --- a/src/DevHive.Data/Repositories/UserRepository.cs +++ b/src/DevHive.Data/Repositories/UserRepository.cs @@ -23,14 +23,6 @@ namespace DevHive.Data.Repositories } #region Read - public IEnumerable<User> QueryAll() - { - return this._context.Users - .Include(x => x.Roles) - .AsNoTracking() - .AsEnumerable(); - } - public override async Task<User> GetByIdAsync(Guid id) { return await this._context.Users @@ -38,8 +30,7 @@ namespace DevHive.Data.Repositories .Include(x => x.Languages) .Include(x => x.Technologies) .Include(x => x.Posts) - .Include(x => x.MyFriends) - .Include(x => x.FriendsOf) + .Include(x => x.Friends) .Include(x => x.ProfilePicture) .FirstOrDefaultAsync(x => x.Id == id); } @@ -51,56 +42,15 @@ namespace DevHive.Data.Repositories .Include(x => x.Languages) .Include(x => x.Technologies) .Include(x => x.Posts) - .Include(x => x.MyFriends) - .Include(x => x.FriendsOf) + .Include(x => x.Friends) .Include(x => x.ProfilePicture) .FirstOrDefaultAsync(x => x.UserName == username); } #endregion #region Update - public override async Task<bool> EditAsync(Guid id, User newEntity) + public async Task<bool> UpdateProfilePicture(Guid userId, string pictureUrl) { - User user = await this.GetByIdAsync(id); - - this._context - .Entry(user) - .CurrentValues - .SetValues(newEntity); - - HashSet<Language> languages = new(); - foreach (var lang in newEntity.Languages) - languages.Add(lang); - user.Languages = languages; - - HashSet<Role> roles = new(); - foreach (var role in newEntity.Roles) - roles.Add(role); - user.Roles = roles; - - foreach (var friend in newEntity.MyFriends) - { - user.MyFriends.Add(friend); - this._context.Entry(friend).State = EntityState.Modified; - } - - foreach (var friend in newEntity.FriendsOf) - { - user.FriendsOf.Add(friend); - this._context.Entry(friend).State = EntityState.Modified; - } - - HashSet<Technology> technologies = new(); - foreach (var tech in newEntity.Technologies) - technologies.Add(tech); - user.Technologies = technologies; - - this._context.Entry(user).State = EntityState.Modified; - - return await this.SaveChangesAsync(); - } - - public async Task<bool> UpdateProfilePicture(Guid userId, string pictureUrl) { User user = await this.GetByIdAsync(userId); user.ProfilePicture.PictureURL = pictureUrl; @@ -131,14 +81,19 @@ namespace DevHive.Data.Repositories .AnyAsync(u => u.Email == email); } - public async Task<bool> DoesUserHaveThisFriendAsync(Guid userId, Guid friendId) + public async Task<bool> ValidateFriendsCollectionAsync(List<string> usernames) { - return true; - // User user = await this.GetByIdAsync(userId); + bool valid = true; - // User friend = await this.GetByIdAsync(friendId); - - // return user.Friends.Any(x => x.Friend.Id == friendId); + foreach (var username in usernames) + { + if (!await this._context.Users.AnyAsync(x => x.UserName == username)) + { + valid = false; + break; + } + } + return valid; } public bool DoesUserHaveThisUsername(Guid id, string username) diff --git a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs index 6922cd7..2b0f4ed 100644 --- a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs @@ -12,27 +12,20 @@ namespace DevHive.Services.Configurations.Mapping { CreateMap<UserServiceModel, User>(); CreateMap<RegisterServiceModel, User>(); - CreateMap<FriendServiceModel, User>(); - // .ForMember(dest => dest.Friends, src => src.Ignore()); - CreateMap<UserFriend, FriendServiceModel>() - .ForMember(dest => dest.UserName, src => src.MapFrom(p => p.Friend.UserName)); + CreateMap<FriendServiceModel, User>() + .ForMember(dest => dest.Friends, src => src.Ignore()); CreateMap<UpdateUserServiceModel, User>() - // .ForMember(dest => dest.Friends, src => src.Ignore()) + .ForMember(dest => dest.Friends, src => src.Ignore()) .AfterMap((src, dest) => dest.PasswordHash = PasswordModifications.GeneratePasswordHash(src.Password)); CreateMap<UpdateFriendServiceModel, User>(); CreateMap<User, UserServiceModel>() - .ForMember(dest => dest.Friends, src => src.MapFrom(p => p.MyFriends)) - .ForMember(dest => dest.ProfilePictureURL, src => src.MapFrom(p => p.ProfilePicture.PictureURL)); - // .ForMember(dest => dest.Friends, src => src.MapFrom(p => p.Friends)); + .ForMember(dest => dest.ProfilePictureURL, src => src.MapFrom(p => p.ProfilePicture.PictureURL)) + .ForMember(dest => dest.Friends, src => src.MapFrom(p => p.Friends)); CreateMap<User, UpdateUserServiceModel>() .ForMember(x => x.Password, opt => opt.Ignore()) .ForMember(dest => dest.ProfilePictureURL, src => src.MapFrom(p => p.ProfilePicture.PictureURL)); CreateMap<User, FriendServiceModel>(); - - CreateMap<UserFriend, FriendServiceModel>() - .ForMember(dest => dest.UserName, src => src.MapFrom(p => p.Friend.UserName)) - .ForMember(dest => dest.Id, src => src.MapFrom(p => p.FriendId)); } } } diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index 9cc4a8e..8f9ebc4 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -14,8 +14,8 @@ using DevHive.Services.Interfaces; using DevHive.Data.Interfaces.Repositories; using System.Linq; using DevHive.Common.Models.Misc; -using DevHive.Data.RelationModels; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Identity; namespace DevHive.Services.Services { @@ -25,6 +25,8 @@ namespace DevHive.Services.Services private readonly IRoleRepository _roleRepository; private readonly ILanguageRepository _languageRepository; private readonly ITechnologyRepository _technologyRepository; + private readonly UserManager<User> _userManager; + private readonly RoleManager<Role> _roleManager; private readonly IMapper _userMapper; private readonly JWTOptions _jwtOptions; private readonly ICloudService _cloudService; @@ -33,6 +35,8 @@ namespace DevHive.Services.Services ILanguageRepository languageRepository, IRoleRepository roleRepository, ITechnologyRepository technologyRepository, + UserManager<User> userManager, + RoleManager<Role> roleManager, IMapper mapper, JWTOptions jwtOptions, ICloudService cloudService) @@ -43,6 +47,8 @@ namespace DevHive.Services.Services this._jwtOptions = jwtOptions; this._languageRepository = languageRepository; this._technologyRepository = technologyRepository; + this._userManager = userManager; + this._roleManager = roleManager; this._cloudService = cloudService; } @@ -77,20 +83,22 @@ namespace DevHive.Services.Services User user = this._userMapper.Map<User>(registerModel); user.PasswordHash = PasswordModifications.GeneratePasswordHash(registerModel.Password); - user.ProfilePicture = new ProfilePicture() { PictureURL = "/assets/images/feed/profile-pic.png" }; + user.ProfilePicture = new ProfilePicture() { PictureURL = string.Empty }; // Make sure the default role exists //TODO: Move when project starts if (!await this._roleRepository.DoesNameExist(Role.DefaultRole)) await this._roleRepository.AddAsync(new Role { Name = Role.DefaultRole }); - // Set the default role to the user - Role defaultRole = await this._roleRepository.GetByNameAsync(Role.DefaultRole); - user.Roles.Add(defaultRole); + user.Roles.Add(await this._roleRepository.GetByNameAsync(Role.DefaultRole)); - await this._userRepository.AddAsync(user); + IdentityResult userResult = await this._userManager.CreateAsync(user); + User createdUser = await this._userRepository.GetByUsernameAsync(registerModel.UserName); - return new TokenModel(WriteJWTSecurityToken(user.Id, user.UserName, user.Roles)); + if (!userResult.Succeeded) + throw new ArgumentException("Unable to create a user"); + + return new TokenModel(WriteJWTSecurityToken(createdUser.Id, createdUser.UserName, createdUser.Roles)); } #endregion @@ -105,9 +113,7 @@ namespace DevHive.Services.Services public async Task<UserServiceModel> GetUserByUsername(string username) { - User user = await this._userRepository.GetByUsernameAsync(username); - - if (user == null) + User user = await this._userRepository.GetByUsernameAsync(username) ?? throw new ArgumentException("User does not exist!"); return this._userMapper.Map<UserServiceModel>(user); @@ -119,16 +125,17 @@ namespace DevHive.Services.Services { await this.ValidateUserOnUpdate(updateUserServiceModel); - User user = await this.PopulateModel(updateUserServiceModel); + User currentUser = await this._userRepository.GetByIdAsync(updateUserServiceModel.Id); + await this.PopulateUserModel(currentUser, updateUserServiceModel); - await this.CreateRelationToFriends(user, updateUserServiceModel.Friends.ToList()); + await this.CreateRelationToFriends(currentUser, updateUserServiceModel.Friends.ToList()); - bool successful = await this._userRepository.EditAsync(updateUserServiceModel.Id, user); + IdentityResult result = await this._userManager.UpdateAsync(currentUser); - if (!successful) + if (!result.Succeeded) throw new InvalidOperationException("Unable to edit user!"); - User newUser = await this._userRepository.GetByIdAsync(user.Id); + User newUser = await this._userRepository.GetByIdAsync(currentUser.Id); return this._userMapper.Map<UserServiceModel>(newUser); } @@ -139,7 +146,7 @@ namespace DevHive.Services.Services { User user = await this._userRepository.GetByIdAsync(updateProfilePictureServiceModel.UserId); - if (!String.IsNullOrEmpty(user.ProfilePicture.PictureURL)) + if (!string.IsNullOrEmpty(user.ProfilePicture.PictureURL)) { bool success = await _cloudService.RemoveFilesFromCloud(new List<string> { user.ProfilePicture.PictureURL }); if (!success) @@ -165,9 +172,9 @@ namespace DevHive.Services.Services throw new ArgumentException("User does not exist!"); User user = await this._userRepository.GetByIdAsync(id); - bool result = await this._userRepository.DeleteAsync(user); + IdentityResult result = await this._userManager.DeleteAsync(user); - return result; + return result.Succeeded; } #endregion @@ -233,9 +240,19 @@ namespace DevHive.Services.Services if (!await this._userRepository.DoesUserExistAsync(updateUserServiceModel.Id)) throw new ArgumentException("User does not exist!"); + if (updateUserServiceModel.Friends.Any(x => x.UserName == updateUserServiceModel.UserName)) + throw new ArgumentException("You cant add yourself as a friend(sry, bro)!"); + if (!this._userRepository.DoesUserHaveThisUsername(updateUserServiceModel.Id, updateUserServiceModel.UserName) && await this._userRepository.DoesUsernameExistAsync(updateUserServiceModel.UserName)) throw new ArgumentException("Username already exists!"); + + List<string> usernames = new(); + foreach (var friend in updateUserServiceModel.Friends) + usernames.Add(friend.UserName); + + if (!await this._userRepository.ValidateFriendsCollectionAsync(usernames)) + throw new ArgumentException("One or more friends do not exist!"); } /// <summary> @@ -288,29 +305,20 @@ namespace DevHive.Services.Services await this._roleRepository.AddAsync(adminRole); } - Role admin = await this._roleRepository.GetByNameAsync(Role.AdminRole); + Role admin = await this._roleManager.FindByNameAsync(Role.AdminRole); user.Roles.Add(admin); - await this._userRepository.EditAsync(user.Id, user); + await this._userManager.UpdateAsync(user); User newUser = await this._userRepository.GetByIdAsync(userId); return new TokenModel(WriteJWTSecurityToken(newUser.Id, newUser.UserName, newUser.Roles)); } - /// <summary> - /// Returns the user with the Id in the model, adding to him the roles, languages and technologies, specified by the parameter model. - /// This practically maps HashSet<UpdateRoleServiceModel> to HashSet<Role> (and the equvalent HashSets for Languages and Technologies) - /// and assigns the latter to the returned user. - /// </summary> - private async Task<User> PopulateModel(UpdateUserServiceModel updateUserServiceModel) + private async Task PopulateUserModel(User user, UpdateUserServiceModel updateUserServiceModel) { - User user = this._userMapper.Map<User>(updateUserServiceModel); - - /* Fetch Roles and replace model's*/ //Do NOT allow a user to change his roles, unless he is an Admin - bool isAdmin = (await this._userRepository.GetByIdAsync(updateUserServiceModel.Id)) - .Roles.Any(r => r.Name == Role.AdminRole); + bool isAdmin = await this._userManager.IsInRoleAsync(user, Role.AdminRole); if (isAdmin) { @@ -324,11 +332,7 @@ namespace DevHive.Services.Services } user.Roles = roles; } - //Preserve original user roles - else - user.Roles = (await this._userRepository.GetByIdAsync(updateUserServiceModel.Id)).Roles; - /* Fetch Languages and replace model's*/ HashSet<Language> languages = new(); int languagesCount = updateUserServiceModel.Languages.Count; for (int i = 0; i < languagesCount; i++) @@ -351,37 +355,19 @@ namespace DevHive.Services.Services technologies.Add(technology); } user.Technologies = technologies; - - return user; } - private async Task<bool> CreateRelationToFriends(User user, List<UpdateFriendServiceModel> friends) + private async Task CreateRelationToFriends(User user, List<UpdateFriendServiceModel> friends) { foreach (var friend in friends) { - User amigo = await this._userRepository.GetByUsernameAsync(friend.UserName) ?? - throw new ArgumentException("No amigo, bro!"); - - UserFriend relation = new() - { - UserId = user.Id, - User = user, - FriendId = amigo.Id, - Friend = amigo - }; + User amigo = await this._userRepository.GetByUsernameAsync(friend.UserName); - UserFriend theOtherRelation = new() - { - UserId = amigo.Id, - User = amigo, - FriendId = user.Id, - Friend = user - }; + user.Friends.Add(amigo); + amigo.Friends.Add(user); - user.MyFriends.Add(relation); - user.FriendsOf.Add(theOtherRelation); + await this._userManager.UpdateAsync(amigo); } - return true; } #endregion } diff --git a/src/DevHive.Web/Configurations/Extensions/ConfigureDatabase.cs b/src/DevHive.Web/Configurations/Extensions/ConfigureDatabase.cs index 3748edf..9f02dd7 100644 --- a/src/DevHive.Web/Configurations/Extensions/ConfigureDatabase.cs +++ b/src/DevHive.Web/Configurations/Extensions/ConfigureDatabase.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.DependencyInjection; -using DevHive.Data.Repositories; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using DevHive.Data.Models; @@ -8,8 +7,6 @@ using Microsoft.AspNetCore.Builder; using System; using Microsoft.AspNetCore.Authentication.JwtBearer; using DevHive.Data; -using Microsoft.AspNetCore.Authorization; -using System.Collections.Generic; namespace DevHive.Web.Configurations.Extensions { diff --git a/src/DevHive.Web/Startup.cs b/src/DevHive.Web/Startup.cs index dd7e852..46521cf 100644 --- a/src/DevHive.Web/Startup.cs +++ b/src/DevHive.Web/Startup.cs @@ -33,7 +33,6 @@ namespace DevHive.Web services.JWTConfiguration(Configuration); services.AutoMapperConfiguration(); services.DependencyInjectionConfiguration(this.Configuration); - services.ExceptionHandlerMiddlewareConfiguration(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. |
