From d0b7e08cfe8416fbde553ce342333c865ae15c9c Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Thu, 31 Oct 2024 17:32:39 -0500 Subject: [PATCH] add update user --- .../Repositories/IBotSharpRepository.cs | 1 + .../Users/IUserService.cs | 1 + .../FileRepository/FileRepository.Agent.cs | 12 ++++- .../FileRepository/FileRepository.User.cs | 36 ++++++++++++++ .../Users/Services/UserService.cs | 6 +++ .../Controllers/UserController.cs | 18 ++++++- .../Users/UserAgentActionViewModel.cs | 10 ++++ .../ViewModels/Users/UserUpdateModel.cs | 49 +++++++++++++++++++ .../Repository/MongoRepository.User.cs | 44 ++++++++++++++++- 9 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 src/Infrastructure/BotSharp.OpenAPI/ViewModels/Users/UserUpdateModel.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs index a2175cc1..f21850e3 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs @@ -33,6 +33,7 @@ public interface IBotSharpRepository void UpdateUserIsDisable(string userId, bool isDisable) => throw new NotImplementedException(); void UpdateUsersIsDisable(List userIds, bool isDisable) => throw new NotImplementedException(); PagedItems GetUsers(UserFilter filter) => throw new NotImplementedException(); + bool UpdateUser(User user, bool isUpdateUserAgents = false) => throw new NotImplementedException(); #endregion #region Agent diff --git a/src/Infrastructure/BotSharp.Abstraction/Users/IUserService.cs b/src/Infrastructure/BotSharp.Abstraction/Users/IUserService.cs index 94f30aad..734884ef 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Users/IUserService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Users/IUserService.cs @@ -7,6 +7,7 @@ public interface IUserService { Task GetUser(string id); Task> GetUsers(UserFilter filter); + Task UpdateUser(User model, bool isUpdateUserAgents = false); Task CreateUser(User user); Task ActiveUser(UserActivationModel model); Task GetAffiliateToken(string authorization); diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs index 71e9ea13..90f05ceb 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs @@ -449,9 +449,15 @@ namespace BotSharp.Core.Repository return true; } - public void BulkInsertAgents(List agents) { } + public void BulkInsertAgents(List agents) + { + _agents = []; + } - public void BulkInsertUserAgents(List userAgents) { } + public void BulkInsertUserAgents(List userAgents) + { + _userAgents = []; + } public bool DeleteAgents() { @@ -487,6 +493,8 @@ namespace BotSharp.Core.Repository // Delete agent folder Directory.Delete(agentDir, true); + _agents = []; + _userAgents = []; return true; } catch diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.User.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.User.cs index 0719509e..9ee6bdb4 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.User.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.User.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Users.Enums; using BotSharp.Abstraction.Users.Models; using System; @@ -130,4 +131,39 @@ public partial class FileRepository Count = users.Count() }; } + + public bool UpdateUser(User user, bool isUpdateUserAgents = false) + { + if (string.IsNullOrEmpty(user?.Id)) return false; + + var dir = Path.Combine(_dbSettings.FileRepository, USERS_FOLDER, user.Id); + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(dir); + } + + var userFile = Path.Combine(dir, USER_FILE); + user.UpdatedTime = DateTime.UtcNow; + File.WriteAllText(_dbSettings.FileRepository, JsonSerializer.Serialize(user, _options)); + + if (isUpdateUserAgents) + { + var userAgents = user.AgentActions?.Select(x => new UserAgent + { + Id = !string.IsNullOrEmpty(x.Id) ? x.Id : Guid.NewGuid().ToString(), + UserId = user.Id, + AgentId = x.AgentId, + Actions = x.Actions ?? [], + CreatedTime = DateTime.UtcNow, + UpdatedTime = DateTime.UtcNow + })?.ToList() ?? []; + + var userAgentFile = Path.Combine(dir, USER_AGENT_FILE); + File.WriteAllText(userAgentFile, JsonSerializer.Serialize(userAgents, _options)); + } + + _users = []; + _userAgents = []; + return true; + } } diff --git a/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs b/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs index 8b228dcd..2098d71d 100644 --- a/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs +++ b/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs @@ -384,6 +384,12 @@ public class UserService : IUserService return users; } + public async Task UpdateUser(User model, bool isUpdateUserAgents = false) + { + var db = _services.GetRequiredService(); + return db.UpdateUser(model, isUpdateUserAgents); + } + public async Task ActiveUser(UserActivationModel model) { var id = model.UserName; diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/UserController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/UserController.cs index d0610dd3..dbb312b0 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/UserController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/UserController.cs @@ -1,5 +1,4 @@ using BotSharp.Abstraction.Users.Enums; -using EntityFrameworkCore.BootKit; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using System.ComponentModel.DataAnnotations; @@ -192,6 +191,23 @@ public class UserController : ControllerBase Items = views }; } + + + [HttpPut("/user")] + public async Task UpdateUser([FromBody] UserUpdateModel model) + { + if (model == null) return false; + + var userService = _services.GetRequiredService(); + var user = await userService.GetUser(_user.Id); + if (user == null || !UserConstant.AdminRoles.Contains(user.Role)) + { + return false; + } + + var updated = await userService.UpdateUser(UserUpdateModel.ToUser(model), isUpdateUserAgents: true); + return updated; + } #endregion diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Users/UserAgentActionViewModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Users/UserAgentActionViewModel.cs index 49c1d6b4..adf3d45b 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Users/UserAgentActionViewModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Users/UserAgentActionViewModel.cs @@ -27,4 +27,14 @@ public class UserAgentActionViewModel Actions = action.Actions }; } + + public static UserAgentAction ToDomainModel(UserAgentActionViewModel action) + { + return new UserAgentAction + { + Id = action.Id, + AgentId = action.AgentId, + Actions = action.Actions + }; + } } diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Users/UserUpdateModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Users/UserUpdateModel.cs new file mode 100644 index 00000000..76b8e347 --- /dev/null +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Users/UserUpdateModel.cs @@ -0,0 +1,49 @@ +using System.Text.Json.Serialization; + +namespace BotSharp.OpenAPI.ViewModels.Users; + +public class UserUpdateModel +{ + public string Id { get; set; } = string.Empty; + + [JsonPropertyName("user_name")] + public string UserName { get; set; } = string.Empty; + + [JsonPropertyName("first_name")] + public string FirstName { get; set; } = string.Empty; + + [JsonPropertyName("last_name")] + public string? LastName { get; set; } + public string? Email { get; set; } + public string? Phone { get; set; } + public string? Type { get; set; } + public string? Role { get; set; } + public string? Source { get; set; } + + [JsonPropertyName("external_id")] + public string? ExternalId { get; set; } + + public IEnumerable Permissions { get; set; } = []; + + [JsonPropertyName("agent_actions")] + public IEnumerable AgentActions { get; set; } = []; + + public static User ToUser(UserUpdateModel model) + { + return new User + { + Id = model.Id, + UserName = model.UserName, + FirstName = model.FirstName, + LastName = model.LastName, + Email = model.Email, + Phone = model.Phone, + Type = model.Type, + Role = model.Role, + Source = model.Source, + ExternalId = model.ExternalId, + Permissions = model.Permissions, + AgentActions = model.AgentActions?.Select(x => UserAgentActionViewModel.ToDomainModel(x)) ?? [] + }; + } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.User.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.User.cs index 540b6508..4bd31fa6 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.User.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.User.cs @@ -1,9 +1,7 @@ using BotSharp.Abstraction.Agents.Models; -using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Users.Enums; using BotSharp.Abstraction.Users.Models; -using System.Globalization; namespace BotSharp.Plugin.MongoStorage.Repository; @@ -231,4 +229,46 @@ public partial class MongoRepository Count = (int)count }; } + + + public bool UpdateUser(User user, bool isUpdateUserAgents = false) + { + if (string.IsNullOrEmpty(user?.Id)) return false; + + var userFilter = Builders.Filter.Eq(x => x.Id, user.Id); + var userUpdate = Builders.Update + .Set(x => x.Role, user.Role) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Users.UpdateOne(userFilter, userUpdate); + + if (isUpdateUserAgents) + { + var userAgentDocs = user.AgentActions?.Select(x => new UserAgentDocument + { + Id = !string.IsNullOrEmpty(x.Id) ? x.Id : Guid.NewGuid().ToString(), + UserId = user.Id, + AgentId = x.AgentId, + Actions = x.Actions, + CreatedTime = DateTime.UtcNow, + UpdatedTime = DateTime.UtcNow + })?.ToList() ?? []; + + _dc.UserAgents.DeleteMany(Builders.Filter.Nin(x => x.Id, userAgentDocs.Select(x => x.Id))); + foreach (var doc in userAgentDocs) + { + var userAgentFilter = Builders.Filter.Eq(x => x.Id, doc.Id); + var userAgentUpdate = Builders.Update + .Set(x => x.Id, doc.Id) + .Set(x => x.UserId, user.Id) + .Set(x => x.AgentId, doc.AgentId) + .Set(x => x.Actions, doc.Actions) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.UserAgents.UpdateOne(userAgentFilter, userAgentUpdate, _options); + } + } + + return true; + } }