private async Task <UserGroupPoco> AddGroupWithPermissionAndUser(int userId, int nodeId) { // add a group with a user UserGroupPoco group = await _groupService.CreateUserGroupAsync("Test Group"); group.Users.Add(new User2UserGroupPoco { GroupId = group.GroupId, UserId = userId }); await _groupService.UpdateUserGroupAsync(group); // give the group permissions to the node var poco = new UserGroupPermissionsPoco { GroupId = group.GroupId, Permission = 0, NodeId = nodeId }; _configService.UpdateNodeConfig(new Dictionary <int, List <UserGroupPermissionsPoco> > { { 0, new List <UserGroupPermissionsPoco> { poco } } }); return(group); }
public async Task <IHttpActionResult> Put(UserGroupPoco group) { try { UserGroupPoco result = await _groupService.UpdateUserGroupAsync(group); // need to check the new name/alias isn't already in use if (result == null) { return(Content(HttpStatusCode.OK, new { status = 500, msg = Constants.GroupNameExists })); } } catch (Exception ex) { Log.Error(Constants.ErrorUpdatingGroup, ex); return(Content(HttpStatusCode.InternalServerError, ViewHelpers.ApiException(ex, Constants.ErrorUpdatingGroup))); } // feedback to the browser string msgText = Constants.GroupUpdated.Replace("{name}", group.Name); Log.Debug(msgText); return(Ok(new { status = 200, msg = msgText })); }
/// <summary> /// Maps Users to the UserGroup property of a UserGroupPermissionsPoco /// </summary> /// <param name="ugpp"></param> /// <param name="ugp"></param> /// <param name="u2Ugp"></param> /// <returns></returns> public UserGroupPermissionsPoco MapIt(UserGroupPermissionsPoco ugpp, UserGroupPoco ugp, User2UserGroupPoco u2Ugp) { if (ugpp == null) { return(Current); } if (Current != null && Current.GroupId == ugpp.GroupId) { if (Current.UserGroup == null) { Current.UserGroup = ugp; } if (Current.GroupId == u2Ugp.GroupId) { Current.UserGroup.Users.Add(u2Ugp); } return(null); } var prev = Current; Current = ugpp; Current.UserGroup = ugp; if (Current.GroupId == u2Ugp.GroupId) { Current.UserGroup.Users.Add(u2Ugp); } return(prev); }
public async Task <IHttpActionResult> Put(UserGroupPoco group) { try { var result = await groupService.UpdateUserGroupAsync(group); // need to check the new name/alias isn't already in use if (result == null) { return(Content(HttpStatusCode.OK, new { status = 500, msg = "Group name already exists" })); } } catch (Exception ex) { const string msg = "An error occurred updating the user group"; Log.Error(msg, ex); return(Content(HttpStatusCode.InternalServerError, ViewHelpers.ApiException(ex, msg))); } // feedback to the browser string msgText = $"User group '{group.Name}' has been saved."; Log.Debug(msgText); return(Ok(new { status = 200, msg = msgText })); }
public async Task <IHttpActionResult> Post([FromBody] Model model) { string name = model.Data; try { UserGroupPoco poco = await _groupService.CreateUserGroupAsync(name); // check that it doesn't already exist if (poco == null) { return(Ok(new { status = 200, success = false, msg = MagicStrings.GroupNameExists })); } string msg = MagicStrings.GroupCreated.Replace("{name}", name); Log.Debug(msg); // return the id of the new group, to update the front-end route to display the edit view return(Ok(new { status = 200, success = true, msg, id = poco.GroupId })); } catch (Exception ex) { string error = $"Error creating user group '{name}' - group has likely been deleted. Group names cannot be reused."; Log.Error(error, ex); // if we are here, something isn't right... return(Content(HttpStatusCode.InternalServerError, ViewHelpers.ApiException(ex, error))); } }
public async Task <IHttpActionResult> Get(int?id = null) { try { if (id.HasValue) { UserGroupPoco result = await _groupService.GetUserGroupAsync(id.Value); if (result != null) { return(Json(result, ViewHelpers.CamelCase)); } } else { return(Json(await _groupService.GetUserGroupsAsync(), ViewHelpers.CamelCase)); } throw new HttpResponseException(HttpStatusCode.NotFound); } catch (Exception e) { string error = MagicStrings.ErrorGettingGroup.Replace("{id}", id.ToString()); Log.Error(error, e); // if we are here, something isn't right... return(Content(HttpStatusCode.InternalServerError, ViewHelpers.ApiException(e, error))); } }
public async void Can_Get_Group_By_Id() { // create a group UserGroupPoco newGroup = await _groupService.CreateUserGroupAsync(Utility.RandomString()); // then use its id to fetch Assert.NotNull(await _groupService.GetUserGroupAsync(newGroup.GroupId)); }
public async Task <UserGroupPoco> AddGroup(UserGroupPoco input) { await _context.UserGroups.AddAsync(input); await _context.SaveChangesAsync(); return(input); }
public async Task <SimpleResult> EditGroup(UserGroupPoco input) { _context.Entry(input).State = EntityState.Modified; await _context.SaveChangesAsync(); return(new SimpleResult { IsSuccess = true }); }
public async void Can_Create_Group_And_Event_Is_Raised() { GroupService.Created += (sender, args) => { Assert.NotNull(args); }; UserGroupPoco newGroup = await _groupService.CreateUserGroupAsync(Utility.RandomString()); Assert.NotNull(newGroup); Assert.True(newGroup.GroupId > 0); }
/// <summary> /// Inserts a new usergroup into the database /// </summary> /// <param name="name">The group name</param> /// <param name="alias">The group alias</param> /// <param name="deleted">The group state</param> /// <returns>The newly created user group, of type <see cref="UserGroupPoco"/></returns> public UserGroupPoco InsertUserGroup(string name, string alias, bool deleted) { var poco = new UserGroupPoco { Name = name, Alias = alias, Deleted = deleted }; _database.Save(poco); return(poco); }
public async Task <SimpleResult> SaveGroup(SaveGroupInput input) { try { if (input.Id != null) { var existingGroup = await _context.UserGroups.FindAsync(input.Id); await _userDomain.UpdateGroup(existingGroup); return(new SimpleResult { IsSuccess = true }); } else { var modules = new List <ModulePoco>(); foreach (var x in input.Modules) { var mod = await _context.Modules.FindAsync(x.Value); modules.Add(mod); } var group = new UserGroupPoco { AccessLevel = (AccessLevel)input.Access.Value, Title = input.Title, Description = input.Description, Modules = JsonConvert.SerializeObject(modules, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }) }; await _userDomain.AddGroup(group); return(new SimpleResult { IsSuccess = true }); } } catch (Exception ex) { return(new SimpleResult { IsSuccess = false, ErrorMessage = JsonConvert.SerializeObject(ex) }); } }
public async void Cannot_Update_Group_If_Name_In_Use() { Scaffold.Config(); var group = new UserGroupPoco { GroupId = 3, Name = "Publisher", Users = new List <User2UserGroupPoco>() }; object result = await(await _groupsController.Put(group)).GetContent(); Assert.Equal(MagicStrings.GroupNameExists, result.Get("msg")); }
public async void Can_Add_Users_To_Group() { string name = Utility.RandomString(); UserGroupPoco group = await _groupService.CreateUserGroupAsync(name); group.Users.Add(Scaffold.GetUser2UserGroupPoco(group.GroupId)); group.Users.Add(Scaffold.GetUser2UserGroupPoco(group.GroupId)); group.Users.Add(Scaffold.GetUser2UserGroupPoco(group.GroupId)); group.Users.Add(Scaffold.GetUser2UserGroupPoco(group.GroupId)); UserGroupPoco updatedGroup = await _groupService.UpdateUserGroupAsync(group); Assert.Equal(4, updatedGroup.Users.Count()); }
public IHttpActionResult Put(UserGroupPoco group) { bool nameExists = Pr.UserGroupsByName(group.Name).Any(); bool aliasExists = Pr.UserGroupsByAlias(group.Alias).Any(); try { UserGroupPoco userGroup = Pr.UserGroupsById(group.GroupId).First(); // need to check the new name/alias isn't already in use if (userGroup.Name != group.Name && nameExists) { return(Content(HttpStatusCode.OK, new { status = 500, msg = "Group name already exists" })); } if (userGroup.Alias != group.Alias && aliasExists) { return(Content(HttpStatusCode.OK, new { status = 500, msg = "Group alias already exists" })); } // Update the Members - TODO - should find a more efficient way to do this... Database db = DatabaseContext.Database; db.Execute("DELETE FROM WorkflowUser2UserGroup WHERE GroupId = @0", userGroup.GroupId); if (group.Users.Count > 0) { foreach (User2UserGroupPoco user in group.Users) { db.Insert(user); } } db.Update(group); } catch (Exception ex) { Log.Error(ex); return(Content(HttpStatusCode.InternalServerError, ViewHelpers.ApiException(ex))); } // feedback to the browser string msgText = $"User group '{group.Name}' has been saved."; Log.Debug(msgText); return(Ok(new { status = 200, msg = msgText })); }
public async void Can_Update_Group() { Scaffold.Config(); var group = new UserGroupPoco { GroupId = 12, Name = "PublisherUpdated", Alias = "publisherUpdated", Users = new List <User2UserGroupPoco>() }; object result = await(await _groupsController.Put(group)).GetContent(); Assert.Equal(MagicStrings.GroupUpdated.Replace("{name}", "PublisherUpdated"), result.Get("msg")); }
public async void Cannot_Update_Group_When_Name_Exists() { string name = Utility.RandomString(); string name2 = Utility.RandomString(); // create two groups, second will be renamed to the first await _groupService.CreateUserGroupAsync(name); UserGroupPoco group = await _groupService.CreateUserGroupAsync(name2); group.Name = name; UserGroupPoco renamedGroup = await _groupService.UpdateUserGroupAsync(group); Assert.Null(renamedGroup); }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <returns></returns> public Task <UserGroupPoco> CreateUserGroupAsync(string name) { string alias = name.Replace(" ", "-"); bool exists = _repo.GroupAliasExists(alias); if (exists) { return(Task.FromResult((UserGroupPoco)null)); } UserGroupPoco group = _repo.InsertUserGroup(name, alias, false); // emit event Created?.Invoke(this, new GroupEventArgs(group)); return(Task.FromResult(group)); }
public async void Cannot_Validate_Request_When_Last_Task_Not_Pending() { Guid guid = Guid.NewGuid(); const int userId = 446; const int nodeId = 3456; UserGroupPoco group = await AddGroupWithPermissionAndUser(userId, nodeId); // create a task on an instance WorkflowTaskPoco task = Scaffold.Task(guid, groupId: group.GroupId, status: (int)TaskStatus.NotRequired); _tasksService.InsertTask(task); _instancesService.InsertInstance(Scaffold.Instance(guid, 1, nodeId)); bool isValid = await _previewService.Validate(nodeId, userId, task.Id, guid); Assert.False(isValid); }
public UserGroupPoco MapIt(UserGroupPoco a, UserGroupPermissionsPoco c, User2UserGroupPoco b) { if (a == null) { return(Current); } if (Current != null && Current.GroupId == b.GroupId) { if (Current.Users.All(u => u.UserId != b.UserId)) { Current.Users.Add(b); } if (Current.Permissions.All(p => p.Id != c.Id)) { Current.Permissions.Add(c); } return(null); } var prev = Current; Current = a; if (Current.GroupId == b.GroupId) { Current.Users = new List <User2UserGroupPoco>() { b }; } if (Current.GroupId == c.GroupId) { Current.Permissions = new List <UserGroupPermissionsPoco>() { c }; } return(prev); }
public async void Can_Validate_Request() { Guid guid = Guid.NewGuid(); const int userId = 11; const int nodeId = 1089; UserGroupPoco group = await AddGroupWithPermissionAndUser(userId, nodeId); // create a task on an instance WorkflowTaskPoco task = Scaffold.Task(guid, groupId: group.GroupId); _tasksService.InsertTask(task); _instancesService.InsertInstance(Scaffold.Instance(guid, 1, nodeId)); // is valid when the user is in the group responsible for the task with the given id // and the task belongs to the given instance by guid // and both the task and instance are related to the given node id bool isValid = await _previewService.Validate(nodeId, userId, task.Id, guid); Assert.True(isValid); // invalid user id isValid = await _previewService.Validate(nodeId, 99, task.Id, guid); Assert.False(isValid); // invalid task id isValid = await _previewService.Validate(nodeId, userId, 11111, guid); Assert.False(isValid); // invalid guid isValid = await _previewService.Validate(nodeId, userId, task.Id, Guid.NewGuid()); Assert.False(isValid); // invalid node id isValid = await _previewService.Validate(43535, userId, task.Id, guid); Assert.False(isValid); }
public Task <UserGroupPoco> CreateUserGroupAsync(string name) { bool existing = repo.UserGroupsByName(name).Any(); if (existing) { return(null); } UserGroupPoco group = repo.InsertUserGroup(name, name.Replace(" ", "-"), false); // emit event OnGroupCreated(new OnGroupCreatedEventArgs { Group = group, CreatedBy = Utility.GetCurrentUser() }); return(Task.FromResult(group)); }
public async void Can_Update_Group_And_Event_Is_Raised() { GroupService.Updated += (sender, args) => { Assert.NotNull(args); }; const string description = "This is an update"; const string email = "*****@*****.**"; UserGroupPoco group = await _groupService.CreateUserGroupAsync(Utility.RandomString()); group.Description = description; group.GroupEmail = email; UserGroupPoco updatedGroup = await _groupService.UpdateUserGroupAsync(group); Assert.Equal(description, updatedGroup.Description); Assert.Equal(email, updatedGroup.GroupEmail); }
public Task <UserGroupPoco> UpdateUserGroupAsync(UserGroupPoco poco) { var nameExists = repo.UserGroupsByName(poco.Name).Any(); var existingPoco = repo.UserGroupsById(poco.GroupId).First(); if (poco.Name != existingPoco.Name && nameExists) { return(Task.FromResult((UserGroupPoco)null)); } repo.DeleteUsersFromGroup(existingPoco.GroupId); foreach (var user in poco.Users) { repo.AddUserToGroup(user); } repo.UpdateUserGroup(poco); return(Task.FromResult(poco)); }
/// <summary> /// Delete from /app_plugins/workflow/preview /// </summary> /// <param name="nodeId"></param> /// <param name="userId"></param> /// <param name="taskId"></param> /// <param name="guid"></param> public async Task <bool> Validate(int nodeId, int userId, int taskId, Guid guid) { List <WorkflowTaskInstancePoco> taskInstances = _tasksService.GetTasksByNodeId(nodeId); if (!taskInstances.Any() || taskInstances.Last().TaskStatus == TaskStatus.Cancelled) { return(false); } // only interested in last active task WorkflowTaskInstancePoco activeTask = taskInstances.OrderBy(t => t.Id).LastOrDefault(t => t.TaskStatus.In(TaskStatus.PendingApproval, TaskStatus.Rejected)); if (activeTask == null) { return(false); } UserGroupPoco group = await _groupService.GetPopulatedUserGroupAsync(activeTask.GroupId); // only valid if the task belongs to the current workflow, and the user is in the current group, and the task id is correct return(activeTask.WorkflowInstanceGuid == guid && group.Users.Any(u => u.UserId == userId) && activeTask.Id == taskId); }
/// <summary> /// /// </summary> /// <param name="poco"></param> /// <returns></returns> public Task <UserGroupPoco> UpdateUserGroupAsync(UserGroupPoco poco) { bool nameExists = _repo.GroupNameExists(poco.Name); UserGroupPoco existingPoco = _repo.GetUserGroupById(poco.GroupId); if (poco.Name != existingPoco.Name && nameExists) { return(Task.FromResult((UserGroupPoco)null)); } _repo.DeleteUsersFromGroup(existingPoco.GroupId); foreach (var user in poco.Users) { _repo.AddUserToGroup(user); } _repo.UpdateUserGroup(poco); Updated?.Invoke(this, new GroupEventArgs(poco)); return(Task.FromResult(poco)); }
/// <summary> /// Maps Users to the UserGroup property of a WorkflowTaskInstance /// </summary> /// <param name="wtip"></param> /// <param name="wip"></param> /// <param name="ugp"></param> /// <returns></returns> public WorkflowInstancePoco MapIt(WorkflowInstancePoco wip, WorkflowTaskInstancePoco wtip, UserGroupPoco ugp) { if (wip == null) { return(Current); } if (ugp.GroupId == wtip.GroupId) { wtip.UserGroup = ugp; } if (Current != null && Current.Guid == wip.Guid) { if (Current.TaskInstances.All(t => t.ApprovalStep != wtip.ApprovalStep)) { Current.TaskInstances.Add(wtip); } return(null); } var prev = Current; Current = wip; Current.TaskInstances.Add(wtip); return(prev); }
/// <summary> /// Persist changes to a usergroup /// </summary> /// <param name="poco">The group to update, of type <see cref="UserGroupPoco"/></param> public void UpdateUserGroup(UserGroupPoco poco) { _database.Update(poco); }
/// <summary> /// Sends an email notification out for the workflow process /// </summary> /// <param name="instance"></param> /// <param name="emailType">the type of email to be sent</param> public async void Send(WorkflowInstancePoco instance, EmailType emailType) { WorkflowSettingsPoco settings = _settingsService.GetSettings(); if (!settings.SendNotifications) { return; } if (!instance.TaskInstances.Any()) { instance.TaskInstances = _tasksService.GetTasksWithGroupByInstanceGuid(instance.Guid); } if (!instance.TaskInstances.Any()) { Log.Error($"Notifications not sent - no tasks exist for instance { instance.Id }"); return; } WorkflowTaskPoco finalTask = null; try { string docTitle = instance.Node.Name; string docUrl = UrlHelpers.GetFullyQualifiedContentEditorUrl(instance.NodeId); WorkflowTaskPoco[] flowTasks = instance.TaskInstances.OrderBy(t => t.ApprovalStep).ToArray(); // always take get the emails for all previous users, sometimes they will be discarded later // easier to just grab em all, rather than doing so conditionally List <string> emailsForAllTaskUsers = new List <string>(); // in the loop, also store the last task to a variable, and keep the populated group var taskIndex = 0; int taskCount = flowTasks.Length; foreach (WorkflowTaskPoco task in flowTasks) { taskIndex += 1; UserGroupPoco group = await _groupService.GetPopulatedUserGroupAsync(task.GroupId); if (group == null) { continue; } emailsForAllTaskUsers.AddRange(group.PreferredEmailAddresses()); if (taskIndex != taskCount) { continue; } finalTask = task; finalTask.UserGroup = group; } if (finalTask == null) { Log.Error("No valid task found for email notifications"); return; } List <string> to = new List <string>(); var body = ""; string typeDescription = instance.WorkflowType.Description(instance.ScheduledDate); string typeDescriptionPast = instance.WorkflowType.DescriptionPastTense(instance.ScheduledDate); switch (emailType) { case EmailType.ApprovalRequest: to = finalTask.UserGroup.PreferredEmailAddresses(); body = string.Format(EmailApprovalRequestString, to.Count > 1 ? "Umbraco user" : finalTask.UserGroup.Name, docUrl, docTitle, instance.AuthorComment, instance.AuthorUser.Name, typeDescription, string.Empty); break; case EmailType.ApprovalRejection: to = emailsForAllTaskUsers; to.Add(instance.AuthorUser.Email); body = string.Format(EmailRejectedString, "Umbraco user", docUrl, docTitle, finalTask.Comment, finalTask.ActionedByUser.Name, typeDescription.ToLower()); break; case EmailType.ApprovedAndCompleted: to = emailsForAllTaskUsers; to.Add(instance.AuthorUser.Email); //Notify web admins to.Add(settings.Email); if (instance.WorkflowType == WorkflowType.Publish) { IPublishedContent n = _utility.GetPublishedContent(instance.NodeId); docUrl = UrlHelpers.GetFullyQualifiedSiteUrl(n.Url); } body = string.Format(EmailApprovedString, "Umbraco user", docUrl, docTitle, typeDescriptionPast.ToLower()) + "<br/>"; body += instance.BuildProcessSummary(); break; case EmailType.ApprovedAndCompletedForScheduler: to = emailsForAllTaskUsers; to.Add(instance.AuthorUser.Email); body = string.Format(EmailApprovedString, "Umbraco user", docUrl, docTitle, typeDescriptionPast.ToLower()) + "<br/>"; body += instance.BuildProcessSummary(); break; case EmailType.WorkflowCancelled: to = emailsForAllTaskUsers; // include the initiator email to.Add(instance.AuthorUser.Email); body = string.Format(EmailCancelledString, "Umbraco user", typeDescription, docUrl, docTitle, finalTask.ActionedByUser.Name, finalTask.Comment); break; case EmailType.SchedulerActionCancelled: break; default: throw new ArgumentOutOfRangeException(nameof(emailType), emailType, null); } if (!to.Any()) { return; } var client = new SmtpClient(); var msg = new MailMessage { Subject = $"{emailType.ToString().ToTitleCase()} - {instance.Node.Name} ({typeDescription})", IsBodyHtml = true, }; if (settings.Email.HasValue()) { msg.From = new MailAddress(settings.Email); } // if offline is permitted, email group members individually as we need the user id in the url if (emailType == EmailType.ApprovalRequest && finalTask.UserGroup.OfflineApproval) { foreach (User2UserGroupPoco user in finalTask.UserGroup.Users) { string offlineString = string.Format(EmailOfflineApprovalString, settings.SiteUrl, instance.NodeId, user.UserId, finalTask.Id, instance.Guid); body = string.Format(EmailApprovalRequestString, user.User.Name, docUrl, docTitle, instance.AuthorComment, instance.AuthorUser.Name, typeDescription, offlineString); msg.To.Clear(); msg.To.Add(user.User.Email); msg.Body = string.Format(EmailBody, msg.Subject, body); client.Send(msg); } } else { msg.To.Add(string.Join(",", to.Distinct())); msg.Body = string.Format(EmailBody, msg.Subject, body); client.Send(msg); } Log.Info($"Email notifications sent for task { finalTask.Id }, to { msg.To }"); } catch (Exception e) { Log.Error($"Error sending notifications for task { finalTask.Id }", e); } }
public GroupEventArgs(UserGroupPoco group) { Group = group; }