Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1662 delete user from judgesoftuniorg #1542

Merged
merged 11 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using OJS.Data.Contracts;
using OJS.Data.Models;

public interface IUsersRepository : IRepository<UserProfile>
public interface IUsersRepository : IDeletableEntityRepository<UserProfile>
{
UserProfile GetByUsername(string username);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using OJS.Data.Repositories.Base;
using OJS.Data.Repositories.Contracts;

public class UsersRepository : EfGenericRepository<UserProfile>, IUsersRepository
public class UsersRepository : EfDeletableEntityRepository<UserProfile>, IUsersRepository
{
public UsersRepository(DbContext context)
: base(context)
Expand All @@ -27,7 +27,11 @@ public UserProfile GetById(string id)

public override void Delete(UserProfile entity)
{
throw new NotImplementedException();
var guid = Guid.NewGuid().ToString();
entity.UserName = guid;
entity.Email = guid + "@deleted.com";
entity.UserSettings = new UserSettings();
base.Delete(entity);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

using OJS.Data;
using OJS.Web.Areas.Administration.Controllers.Common;
using OJS.Web.Areas.Administration.ViewModels.User;
using OJS.Web.Common.Extensions;

using ViewModelType = OJS.Web.Areas.Administration.ViewModels.User.UserProfileAdministrationViewModel;

Expand Down Expand Up @@ -40,6 +42,54 @@ public ActionResult Index()
return this.View();
}

[HttpGet]
public ActionResult Delete(string id)
{
var user = this.Data.Users.All().Where(u => u.Id == id).Select(UserProfileDeleteViewModel.FromUserProfile).FirstOrDefault();

if (user == null)
{
this.TempData.AddDangerMessage("User not found.");
return this.RedirectToAction(nameof(this.Index));
}

return this.View(user);
}

[HttpPost]
public ActionResult Delete(UserProfileDeleteViewModel model)
{
if (model.InitiatorUsername != this.UserProfile.UserName)
{
this.ModelState.AddModelError(nameof(model.InitiatorUsername), "You must enter your username.");
return this.View(model);
}

var userProfile = this.Data.Users.All().FirstOrDefault(u => u.Id == model.Id);

if (userProfile != null)
{
// Store user info in variables for temp message, because after Delete, they are modified.
var username = userProfile.UserName;
var email = userProfile.Email;

this.Data.Users.Delete(userProfile);
this.Data.AccessLogs.Add(new Data.Models.AccessLog
{
UserId = this.UserProfile.Id,
IpAddress = this.Request.UserHostAddress,
RequestType = "DELETE",
PostParams = $"Deleted user with Id {userProfile.Id}. New username is: {userProfile.UserName} and email is: {userProfile.Email}",
});

this.Data.SaveChanges();

this.TempData.AddWarningMessage($"User {username} with email {email} deleted successfully. If this was a mistake, contact support immediately.");
}

return this.RedirectToAction(nameof(this.Index));
}

[HttpPost]
public ActionResult Update([DataSourceRequest]DataSourceRequest request, ViewModelType model)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace OJS.Web.Areas.Administration.ViewModels.User
{
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq.Expressions;
using System.Web.Mvc;
using OJS.Common.DataAnnotations;
using OJS.Data.Models;

using static OJS.Common.Constants.EditorTemplateConstants;

public class UserProfileDeleteViewModel
{
[ExcludeFromExcel]
public static Expression<Func<UserProfile, UserProfileDeleteViewModel>> FromUserProfile =>
user => new UserProfileDeleteViewModel
{
Id = user.Id,
Username = user.UserName,
Email = user.Email,
};

[HiddenInput(DisplayValue = false)]
public string Id { get; set; }

public string Username { get; set; }

public string Email { get; set; }

[Display(Name = "Enter your username to confirm deletion")]
[UIHint(SingleLineText)]
public string InitiatorUsername { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
@using OJS.Web.Areas.Administration.Controllers
@using OJS.Web.Areas.Administration.ViewModels.User

@using SharedResource = Resources.Areas.Administration.AdministrationGeneral;

@model UserProfileDeleteViewModel

@{
ViewBag.Title = $"Delete user {Model.Username}";
var returnUrl = Url.Action("Index", "Users");
}

<h1 class="text-danger">&nbsp;<span class="glyphicon glyphicon-warning-sign"></span> @ViewBag.Title</h1>
<div class="container ">
@using (Html.BeginForm<UsersController>(c => c.Delete((UserProfileDeleteViewModel)null), FormMethod.Post))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(u => u.Id)

<div class="alert" style="font-size: 2em">
<p>Are you sure you want to delete profile?</p>
<p><b>Username: @Model.Username</b></p>
<p><b>Email: @Model.Email</b></p>
<p>This will delete the user and all its related information, including submissions, scores and participations in contests.</p>
<p class="text-danger">The action cannot be reverted!!!</p>
</div>

<div class="row">
<div class="editor-label col-xs-3">
<div class="pull-right">
@Html.LabelFor(m => m.InitiatorUsername)
</div>
</div>
<div class="editor-field col-xs-4">
@Html.EditorFor(m => m.InitiatorUsername, new { @class = "form-control pull-left full-editor" })
</div>
<div class="editor-field col-xs-4">
@Html.ValidationMessageFor(m => m.InitiatorUsername)
</div>
</div>
<br />
<div class="editor-label">
<div>
<input type="submit" class="btn btn-danger pull-left" value="@SharedResource.Delete" disabled onclick="this.disabled = true; this.form.submit();" />
</div>
<div class="col-xs-4">
<a href=@returnUrl class="btn btn-primary">@SharedResource.Cancel</a>
</div>
</div>
}
</div>

@section Scripts{
<script>
$(function () {
// Attach an event listener to the initiator username input field.
$('#InitiatorUsername').on('input', function () {
var enteredUsername = $(this).val().trim();
var deleteButton = $("input[type='submit'].btn-danger");

// Enable the delete button only when the initiator has entered username.
if (enteredUsername) {
deleteButton.prop('disabled', false);
} else {
deleteButton.prop('disabled', true);
}
});
})
</script>
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
columns.Bound(model => model.CreatedOn).Format(GlobalConstants.DefaultDateTimeFormatString).Hidden();
columns.Bound(model => model.ModifiedOn).Format(GlobalConstants.DefaultDateTimeFormatString).Hidden();
columns.Command(command => command.Edit().Text(" ").UpdateText(GeneralResource.Change).CancelText(GeneralResource.Cancel)).Width(80);
columns.Template(@<text></text>).ClientTemplate($"<a class='k-button' href='Users/Delete/#=Id#'>Delete</a>").Width(80).Title("");
})
.ToolBar(toolbar =>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace OJS.Web.Controllers
{
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
Expand Down Expand Up @@ -202,13 +203,14 @@ private ActionResult RedirectToExternalSystemMessage() => this.RedirectToAction(

private void AddOrUpdateUser(UserProfile user)
{
var existingUser = this.Data.Users.GetById(user.Id);
var existingUser = this.Data.Users.AllWithDeleted().Where(u => u.Id == user.Id).FirstOrDefault();
if (existingUser == null)
{
this.Data.Users.Add(user);
}
else
{
existingUser.UserName = user.UserName;
existingUser.PasswordHash = user.PasswordHash;
existingUser.SecurityStamp = user.SecurityStamp;
existingUser.Email = user.Email;
Expand Down
2 changes: 2 additions & 0 deletions Open Judge System/Web/OJS.Web/OJS.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -1845,6 +1845,7 @@
<Compile Include="Areas\Administration\ViewModels\TestRun\TestRunViewModel.cs" />
<Compile Include="Areas\Administration\ViewModels\Test\TestViewModel.cs" />
<Compile Include="Areas\Administration\ViewModels\User\UserProfileAdministrationViewModel.cs" />
<Compile Include="Areas\Administration\ViewModels\User\UserProfileDeleteViewModel.cs" />
<Compile Include="Areas\Administration\ViewModels\User\UserProfileSimpleAdministrationViewModel.cs" />
<Compile Include="Areas\Api\ApiAreaRegistration.cs" />
<Compile Include="Areas\Api\Controllers\ApiController.cs" />
Expand Down Expand Up @@ -2609,6 +2610,7 @@
<Content Include="Areas\Administration\Views\Contests\_ChangeParticipationEndTimeByTimeInterval.cshtml" />
<Content Include="Areas\Administration\Views\Shared\_CopyAllProblemGroupsToAnotherContest.cshtml" />
<Content Include="Areas\Administration\Views\Contests\CalculateContestLoad.cshtml" />
<Content Include="Areas\Administration\Views\Users\Delete.cshtml" />
<None Include="Properties\PublishProfiles\Dev Suls Judge System.pubxml" />
<None Include="Properties\PublishProfiles\File System.pubxml" />
<None Include="Properties\PublishProfiles\Judge Global.pubxml" />
Expand Down