From 35df9a3994781c16628a494f629cceec3d3e8424 Mon Sep 17 00:00:00 2001 From: sei-tspencer Date: Thu, 9 May 2024 17:04:41 -0400 Subject: [PATCH] add CanManageTeam permission --- Cite.Api.Data/Models/TeamUser.cs | 1 + ...240509202249_team-user-manager.Designer.cs | 1235 +++++++++++++++++ .../20240509202249_team-user-manager.cs | 26 + .../Migrations/CiteContextModelSnapshot.cs | 9 +- Cite.Api/Cite.Api.csproj | 2 +- Cite.Api/Controllers/TeamUserController.cs | 34 + Cite.Api/Services/TeamUserService.cs | 25 + Cite.Api/ViewModels/TeamUser.cs | 1 + 8 files changed, 1327 insertions(+), 6 deletions(-) create mode 100644 Cite.Api.Migrations.PostgreSQL/Migrations/20240509202249_team-user-manager.Designer.cs create mode 100644 Cite.Api.Migrations.PostgreSQL/Migrations/20240509202249_team-user-manager.cs diff --git a/Cite.Api.Data/Models/TeamUser.cs b/Cite.Api.Data/Models/TeamUser.cs index eb1a238..f4d0d32 100755 --- a/Cite.Api.Data/Models/TeamUser.cs +++ b/Cite.Api.Data/Models/TeamUser.cs @@ -32,6 +32,7 @@ public TeamUserEntity(Guid userId, Guid teamId) public Boolean CanIncrementMove { get; set; } public Boolean CanModify { get; set; } public Boolean CanSubmit { get; set; } + public Boolean CanManageTeam { get; set; } } public class TeamUserConfiguration : IEntityTypeConfiguration diff --git a/Cite.Api.Migrations.PostgreSQL/Migrations/20240509202249_team-user-manager.Designer.cs b/Cite.Api.Migrations.PostgreSQL/Migrations/20240509202249_team-user-manager.Designer.cs new file mode 100644 index 0000000..cbdf384 --- /dev/null +++ b/Cite.Api.Migrations.PostgreSQL/Migrations/20240509202249_team-user-manager.Designer.cs @@ -0,0 +1,1235 @@ +// +using System; +using Cite.Api.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Cite.Api.Migrations.PostgreSQL.Migrations +{ + [DbContext(typeof(CiteContext))] + [Migration("20240509202249_team-user-manager")] + partial class teamusermanager + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "uuid-ossp"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Cite.Api.Data.Models.ActionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("ActionNumber") + .HasColumnType("integer") + .HasColumnName("action_number"); + + b.Property("ChangedBy") + .HasColumnType("uuid") + .HasColumnName("changed_by"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("EvaluationId") + .HasColumnType("uuid") + .HasColumnName("evaluation_id"); + + b.Property("InjectNumber") + .HasColumnType("integer") + .HasColumnName("inject_number"); + + b.Property("IsChecked") + .HasColumnType("boolean") + .HasColumnName("is_checked"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MoveNumber") + .HasColumnType("integer") + .HasColumnName("move_number"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationId"); + + b.HasIndex("TeamId"); + + b.ToTable("actions"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.EvaluationEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("CurrentMoveNumber") + .HasColumnType("integer") + .HasColumnName("current_move_number"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("GalleryExhibitId") + .HasColumnType("uuid") + .HasColumnName("gallery_exhibit_id"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("ScoringModelId") + .HasColumnType("uuid") + .HasColumnName("scoring_model_id"); + + b.Property("SituationDescription") + .HasColumnType("text") + .HasColumnName("situation_description"); + + b.Property("SituationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("situation_time"); + + b.Property("Status") + .HasColumnType("integer") + .HasColumnName("status"); + + b.HasKey("Id"); + + b.HasIndex("ScoringModelId"); + + b.ToTable("evaluations"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.MoveEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("EvaluationId") + .HasColumnType("uuid") + .HasColumnName("evaluation_id"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MoveNumber") + .HasColumnType("integer") + .HasColumnName("move_number"); + + b.Property("SituationDescription") + .HasColumnType("text") + .HasColumnName("situation_description"); + + b.Property("SituationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("situation_time"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationId", "MoveNumber") + .IsUnique(); + + b.ToTable("moves"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.PermissionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Key") + .HasColumnType("text") + .HasColumnName("key"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("ReadOnly") + .HasColumnType("boolean") + .HasColumnName("read_only"); + + b.Property("Value") + .HasColumnType("text") + .HasColumnName("value"); + + b.HasKey("Id"); + + b.HasIndex("Key", "Value") + .IsUnique(); + + b.ToTable("permissions"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.RoleEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("EvaluationId") + .HasColumnType("uuid") + .HasColumnName("evaluation_id"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationId"); + + b.HasIndex("TeamId"); + + b.ToTable("roles"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.RoleUserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("RoleId") + .HasColumnType("uuid") + .HasColumnName("role_id"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.HasIndex("UserId", "RoleId") + .IsUnique(); + + b.ToTable("role_users"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.ScoringCategoryEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CalculationEquation") + .HasColumnType("text") + .HasColumnName("calculation_equation"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("DisplayOrder") + .HasColumnType("integer") + .HasColumnName("display_order"); + + b.Property("IsModifierRequired") + .HasColumnType("boolean") + .HasColumnName("is_modifier_required"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MoveNumberFirstDisplay") + .HasColumnType("integer") + .HasColumnName("move_number_first_display"); + + b.Property("MoveNumberLastDisplay") + .HasColumnType("integer") + .HasColumnName("move_number_last_display"); + + b.Property("ScoringModelId") + .HasColumnType("uuid") + .HasColumnName("scoring_model_id"); + + b.Property("ScoringOptionSelection") + .HasColumnType("integer") + .HasColumnName("scoring_option_selection"); + + b.Property("ScoringWeight") + .HasColumnType("double precision") + .HasColumnName("scoring_weight"); + + b.HasKey("Id"); + + b.HasIndex("ScoringModelId"); + + b.ToTable("scoring_categories"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.ScoringModelEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CalculationEquation") + .HasColumnType("text") + .HasColumnName("calculation_equation"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("DisplayCommentTextBoxes") + .HasColumnType("boolean") + .HasColumnName("display_comment_text_boxes"); + + b.Property("DisplayScoringModelByMoveNumber") + .HasColumnType("boolean") + .HasColumnName("display_scoring_model_by_move_number"); + + b.Property("HideScoresOnScoreSheet") + .HasColumnType("boolean") + .HasColumnName("hide_scores_on_score_sheet"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("RightSideDisplay") + .HasColumnType("integer") + .HasColumnName("right_side_display"); + + b.Property("RightSideEmbeddedUrl") + .HasColumnType("text") + .HasColumnName("right_side_embedded_url"); + + b.Property("RightSideHtmlBlock") + .HasColumnType("text") + .HasColumnName("right_side_html_block"); + + b.Property("ShowPastSituationDescriptions") + .HasColumnType("boolean") + .HasColumnName("show_past_situation_descriptions"); + + b.Property("Status") + .HasColumnType("integer") + .HasColumnName("status"); + + b.Property("UseOfficialScore") + .HasColumnType("boolean") + .HasColumnName("use_official_score"); + + b.Property("UseSubmit") + .HasColumnType("boolean") + .HasColumnName("use_submit"); + + b.Property("UseTeamAverageScore") + .HasColumnType("boolean") + .HasColumnName("use_team_average_score"); + + b.Property("UseTeamScore") + .HasColumnType("boolean") + .HasColumnName("use_team_score"); + + b.Property("UseTypeAverageScore") + .HasColumnType("boolean") + .HasColumnName("use_type_average_score"); + + b.Property("UseUserScore") + .HasColumnType("boolean") + .HasColumnName("use_user_score"); + + b.HasKey("Id"); + + b.ToTable("scoring_models"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.ScoringOptionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("DisplayOrder") + .HasColumnType("integer") + .HasColumnName("display_order"); + + b.Property("IsModifier") + .HasColumnType("boolean") + .HasColumnName("is_modifier"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("ScoringCategoryId") + .HasColumnType("uuid") + .HasColumnName("scoring_category_id"); + + b.Property("Value") + .HasColumnType("double precision") + .HasColumnName("value"); + + b.HasKey("Id"); + + b.HasIndex("ScoringCategoryId"); + + b.ToTable("scoring_options"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.SubmissionCategoryEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("Score") + .HasColumnType("double precision") + .HasColumnName("score"); + + b.Property("ScoringCategoryId") + .HasColumnType("uuid") + .HasColumnName("scoring_category_id"); + + b.Property("SubmissionId") + .HasColumnType("uuid") + .HasColumnName("submission_id"); + + b.HasKey("Id"); + + b.HasIndex("ScoringCategoryId"); + + b.HasIndex("SubmissionId"); + + b.ToTable("submission_categories"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.SubmissionCommentEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("SubmissionOptionId") + .HasColumnType("uuid") + .HasColumnName("submission_option_id"); + + b.HasKey("Id"); + + b.HasIndex("SubmissionOptionId"); + + b.ToTable("submission_comments"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.SubmissionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("EvaluationId") + .HasColumnType("uuid") + .HasColumnName("evaluation_id"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MoveNumber") + .HasColumnType("integer") + .HasColumnName("move_number"); + + b.Property("Score") + .HasColumnType("double precision") + .HasColumnName("score"); + + b.Property("ScoringModelId") + .HasColumnType("uuid") + .HasColumnName("scoring_model_id"); + + b.Property("Status") + .HasColumnType("integer") + .HasColumnName("status"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("ScoringModelId"); + + b.HasIndex("TeamId"); + + b.HasIndex("UserId"); + + b.HasIndex("EvaluationId", "UserId", "TeamId", "MoveNumber") + .IsUnique(); + + b.ToTable("submissions"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.SubmissionOptionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("IsSelected") + .HasColumnType("boolean") + .HasColumnName("is_selected"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("ScoringOptionId") + .HasColumnType("uuid") + .HasColumnName("scoring_option_id"); + + b.Property("SubmissionCategoryId") + .HasColumnType("uuid") + .HasColumnName("submission_category_id"); + + b.HasKey("Id"); + + b.HasIndex("ScoringOptionId"); + + b.HasIndex("SubmissionCategoryId"); + + b.ToTable("submission_options"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.TeamEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("EvaluationId") + .HasColumnType("uuid") + .HasColumnName("evaluation_id"); + + b.Property("HideScoresheet") + .HasColumnType("boolean") + .HasColumnName("hide_scoresheet"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("ShortName") + .HasColumnType("text") + .HasColumnName("short_name"); + + b.Property("TeamTypeId") + .HasColumnType("uuid") + .HasColumnName("team_type_id"); + + b.HasKey("Id"); + + b.HasIndex("EvaluationId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("TeamTypeId"); + + b.ToTable("teams"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.TeamTypeEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("IsOfficialScoreContributor") + .HasColumnType("boolean") + .HasColumnName("is_official_score_contributor"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("ShowTeamTypeAverage") + .HasColumnType("boolean") + .HasColumnName("show_team_type_average"); + + b.HasKey("Id"); + + b.ToTable("team_types"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.TeamUserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CanIncrementMove") + .HasColumnType("boolean") + .HasColumnName("can_increment_move"); + + b.Property("CanManageTeam") + .HasColumnType("boolean") + .HasColumnName("can_manage_team"); + + b.Property("CanModify") + .HasColumnType("boolean") + .HasColumnName("can_modify"); + + b.Property("CanSubmit") + .HasColumnType("boolean") + .HasColumnName("can_submit"); + + b.Property("IsObserver") + .HasColumnType("boolean") + .HasColumnName("is_observer"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("TeamId"); + + b.HasIndex("UserId", "TeamId") + .IsUnique(); + + b.ToTable("team_users"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.UserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("users"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.UserPermissionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("PermissionId") + .HasColumnType("uuid") + .HasColumnName("permission_id"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("PermissionId"); + + b.HasIndex("UserId", "PermissionId") + .IsUnique(); + + b.ToTable("user_permissions"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.ActionEntity", b => + { + b.HasOne("Cite.Api.Data.Models.EvaluationEntity", "Evaluation") + .WithMany() + .HasForeignKey("EvaluationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Cite.Api.Data.Models.TeamEntity", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Evaluation"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.EvaluationEntity", b => + { + b.HasOne("Cite.Api.Data.Models.ScoringModelEntity", "ScoringModel") + .WithMany() + .HasForeignKey("ScoringModelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ScoringModel"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.MoveEntity", b => + { + b.HasOne("Cite.Api.Data.Models.EvaluationEntity", "Evaluation") + .WithMany("Moves") + .HasForeignKey("EvaluationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Evaluation"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.RoleEntity", b => + { + b.HasOne("Cite.Api.Data.Models.EvaluationEntity", "Evaluation") + .WithMany() + .HasForeignKey("EvaluationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Cite.Api.Data.Models.TeamEntity", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Evaluation"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.RoleUserEntity", b => + { + b.HasOne("Cite.Api.Data.Models.RoleEntity", "Role") + .WithMany("RoleUsers") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Cite.Api.Data.Models.UserEntity", "User") + .WithMany("RoleUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Role"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.ScoringCategoryEntity", b => + { + b.HasOne("Cite.Api.Data.Models.ScoringModelEntity", "ScoringModel") + .WithMany("ScoringCategories") + .HasForeignKey("ScoringModelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ScoringModel"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.ScoringOptionEntity", b => + { + b.HasOne("Cite.Api.Data.Models.ScoringCategoryEntity", "ScoringCategory") + .WithMany("ScoringOptions") + .HasForeignKey("ScoringCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ScoringCategory"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.SubmissionCategoryEntity", b => + { + b.HasOne("Cite.Api.Data.Models.ScoringCategoryEntity", "ScoringCategory") + .WithMany() + .HasForeignKey("ScoringCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Cite.Api.Data.Models.SubmissionEntity", "Submission") + .WithMany("SubmissionCategories") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ScoringCategory"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.SubmissionCommentEntity", b => + { + b.HasOne("Cite.Api.Data.Models.SubmissionOptionEntity", "SubmissionOption") + .WithMany("SubmissionComments") + .HasForeignKey("SubmissionOptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("SubmissionOption"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.SubmissionEntity", b => + { + b.HasOne("Cite.Api.Data.Models.EvaluationEntity", "Evaluation") + .WithMany("Submissions") + .HasForeignKey("EvaluationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Cite.Api.Data.Models.ScoringModelEntity", "ScoringModel") + .WithMany() + .HasForeignKey("ScoringModelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Cite.Api.Data.Models.TeamEntity", "Team") + .WithMany("Submissions") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Cite.Api.Data.Models.UserEntity", "User") + .WithMany("Submissions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Evaluation"); + + b.Navigation("ScoringModel"); + + b.Navigation("Team"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.SubmissionOptionEntity", b => + { + b.HasOne("Cite.Api.Data.Models.ScoringOptionEntity", "ScoringOption") + .WithMany() + .HasForeignKey("ScoringOptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Cite.Api.Data.Models.SubmissionCategoryEntity", "SubmissionCategory") + .WithMany("SubmissionOptions") + .HasForeignKey("SubmissionCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ScoringOption"); + + b.Navigation("SubmissionCategory"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.TeamEntity", b => + { + b.HasOne("Cite.Api.Data.Models.EvaluationEntity", "Evaluation") + .WithMany("Teams") + .HasForeignKey("EvaluationId"); + + b.HasOne("Cite.Api.Data.Models.TeamTypeEntity", "TeamType") + .WithMany() + .HasForeignKey("TeamTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Evaluation"); + + b.Navigation("TeamType"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.TeamUserEntity", b => + { + b.HasOne("Cite.Api.Data.Models.TeamEntity", "Team") + .WithMany("TeamUsers") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Cite.Api.Data.Models.UserEntity", "User") + .WithMany("TeamUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Team"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.UserPermissionEntity", b => + { + b.HasOne("Cite.Api.Data.Models.PermissionEntity", "Permission") + .WithMany("UserPermissions") + .HasForeignKey("PermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Cite.Api.Data.Models.UserEntity", "User") + .WithMany("UserPermissions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Permission"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.EvaluationEntity", b => + { + b.Navigation("Moves"); + + b.Navigation("Submissions"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.PermissionEntity", b => + { + b.Navigation("UserPermissions"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.RoleEntity", b => + { + b.Navigation("RoleUsers"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.ScoringCategoryEntity", b => + { + b.Navigation("ScoringOptions"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.ScoringModelEntity", b => + { + b.Navigation("ScoringCategories"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.SubmissionCategoryEntity", b => + { + b.Navigation("SubmissionOptions"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.SubmissionEntity", b => + { + b.Navigation("SubmissionCategories"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.SubmissionOptionEntity", b => + { + b.Navigation("SubmissionComments"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.TeamEntity", b => + { + b.Navigation("Submissions"); + + b.Navigation("TeamUsers"); + }); + + modelBuilder.Entity("Cite.Api.Data.Models.UserEntity", b => + { + b.Navigation("RoleUsers"); + + b.Navigation("Submissions"); + + b.Navigation("TeamUsers"); + + b.Navigation("UserPermissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Cite.Api.Migrations.PostgreSQL/Migrations/20240509202249_team-user-manager.cs b/Cite.Api.Migrations.PostgreSQL/Migrations/20240509202249_team-user-manager.cs new file mode 100644 index 0000000..576ab2f --- /dev/null +++ b/Cite.Api.Migrations.PostgreSQL/Migrations/20240509202249_team-user-manager.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Cite.Api.Migrations.PostgreSQL.Migrations +{ + public partial class teamusermanager : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "can_manage_team", + table: "team_users", + type: "boolean", + nullable: false, + defaultValue: false); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "can_manage_team", + table: "team_users"); + } + } +} diff --git a/Cite.Api.Migrations.PostgreSQL/Migrations/CiteContextModelSnapshot.cs b/Cite.Api.Migrations.PostgreSQL/Migrations/CiteContextModelSnapshot.cs index cd4c18d..f03638b 100644 --- a/Cite.Api.Migrations.PostgreSQL/Migrations/CiteContextModelSnapshot.cs +++ b/Cite.Api.Migrations.PostgreSQL/Migrations/CiteContextModelSnapshot.cs @@ -1,8 +1,3 @@ -/* - Copyright 2024 Carnegie Mellon University. All Rights Reserved. - Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information. -*/ - // using System; using Cite.Api.Data; @@ -838,6 +833,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("boolean") .HasColumnName("can_increment_move"); + b.Property("CanManageTeam") + .HasColumnType("boolean") + .HasColumnName("can_manage_team"); + b.Property("CanModify") .HasColumnType("boolean") .HasColumnName("can_modify"); diff --git a/Cite.Api/Cite.Api.csproj b/Cite.Api/Cite.Api.csproj index abbb261..d0bd399 100755 --- a/Cite.Api/Cite.Api.csproj +++ b/Cite.Api/Cite.Api.csproj @@ -1,7 +1,7 @@  - 1.6.1-rc1 + 1.6.1-rc2 net6.0 bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml CS1591 diff --git a/Cite.Api/Controllers/TeamUserController.cs b/Cite.Api/Controllers/TeamUserController.cs index 5b59c56..8ee0724 100755 --- a/Cite.Api/Controllers/TeamUserController.cs +++ b/Cite.Api/Controllers/TeamUserController.cs @@ -175,6 +175,40 @@ public async Task ClearIncrementer([FromRoute] Guid id, Cancellat return Ok(result); } + /// + /// Sets the selected TeamUser manager flag + /// + /// + /// Sets the TeamUser to an manager. + /// + /// The Id of the TeamUser to update + /// + [HttpPut("teamusers/{id}/manager/set")] + [ProducesResponseType(typeof(TeamUser), (int)HttpStatusCode.OK)] + [SwaggerOperation(OperationId = "setManager")] + public async Task SetManager([FromRoute] Guid id, CancellationToken ct) + { + var result = await _teamUserService.SetManagerAsync(id, true, ct); + return Ok(result); + } + + /// + /// Clears the selected TeamUser manager flag + /// + /// + /// Clears the TeamUser from being an manager. + /// + /// The Id of the TeamUser to update + /// + [HttpPut("teamusers/{id}/manager/clear")] + [ProducesResponseType(typeof(TeamUser), (int)HttpStatusCode.OK)] + [SwaggerOperation(OperationId = "clearManager")] + public async Task ClearManager([FromRoute] Guid id, CancellationToken ct) + { + var result = await _teamUserService.SetManagerAsync(id, false, ct); + return Ok(result); + } + /// /// Sets the selected TeamUser modifier flag /// diff --git a/Cite.Api/Services/TeamUserService.cs b/Cite.Api/Services/TeamUserService.cs index 4f4de88..3ef3951 100755 --- a/Cite.Api/Services/TeamUserService.cs +++ b/Cite.Api/Services/TeamUserService.cs @@ -29,6 +29,7 @@ public interface ITeamUserService Task CreateAsync(ViewModels.TeamUser teamUser, CancellationToken ct); Task SetObserverAsync(Guid id, bool value, CancellationToken ct); Task SetIncrementerAsync(Guid id, bool value, CancellationToken ct); + Task SetManagerAsync(Guid id, bool value, CancellationToken ct); Task SetModifierAsync(Guid id, bool value, CancellationToken ct); Task SetSubmitterAsync(Guid id, bool value, CancellationToken ct); Task DeleteAsync(Guid id, CancellationToken ct); @@ -188,6 +189,30 @@ public TeamUserService(CiteContext context, IAuthorizationService authorizationS return _mapper.Map(teamUserToUpdate); } + public async Task SetManagerAsync(Guid id, bool value, CancellationToken ct) + { + if (!(await _authorizationService.AuthorizeAsync(_user, null, new ContentDeveloperRequirement())).Succeeded) + throw new ForbiddenException(); + + var teamUserToUpdate = await _context.TeamUsers + .Include(tu => tu.User) + .SingleOrDefaultAsync(v => v.Id == id, ct); + if (teamUserToUpdate == null) + throw new EntityNotFoundException(); + + teamUserToUpdate.CanManageTeam = value; + await _context.SaveChangesAsync(ct); + if (value) + { + _logger.LogWarning($"User {teamUserToUpdate.UserId} set as manager on team {teamUserToUpdate.TeamId} by {_user.GetId()}"); + } + else + { + _logger.LogWarning($"User {teamUserToUpdate.UserId} removed as manager on team {teamUserToUpdate.TeamId} by {_user.GetId()}"); + } + return _mapper.Map(teamUserToUpdate); + } + public async Task SetModifierAsync(Guid id, bool value, CancellationToken ct) { if (!(await _authorizationService.AuthorizeAsync(_user, null, new ContentDeveloperRequirement())).Succeeded) diff --git a/Cite.Api/ViewModels/TeamUser.cs b/Cite.Api/ViewModels/TeamUser.cs index 2045296..545ec86 100755 --- a/Cite.Api/ViewModels/TeamUser.cs +++ b/Cite.Api/ViewModels/TeamUser.cs @@ -28,6 +28,7 @@ public TeamUser(Guid userId, Guid teamId) public Boolean CanIncrementMove { get; set; } public Boolean CanModify { get; set; } public Boolean CanSubmit { get; set; } + public Boolean CanManageTeam { get; set; } } }