/// <summary> /// Enable Feature for the Feature Group /// </summary> /// <exception cref="ArgumentException">The feature already exists in group</exception> /// <exception cref="ResourceNotFoundException{Feature}">There is no feature with the specified ID</exception> /// <exception cref="ResourceNotFoundException{FeatureGroup}">There is no group with the specified ID</exception> public FeatureToFeatureGroupMapping EnableFeautureForGroup(int featureId, int groupId) { var feature = GetFeature(featureId, loadParent: true, loadChildren: true, loadGroups: true); if (feature == null) { throw new ResourceNotFoundException <Feature>(featureId); } var group = GetGroup(groupId, loadFeatures: true); if (group == null) { throw new ResourceNotFoundException <FeatureGroup>(groupId); } if (group.EnabledFeatures.Any(x => x.FeatureId == featureId)) { throw new ArgumentException($"A feature '{featureId}' already exists in group '{groupId}'"); } var mapping = new FeatureToFeatureGroupMapping(feature, group); feature.GroupsWhereEnabled.Add(mapping); group.EnabledFeatures.Add(mapping); Db.FeatureToFeatureGroupMappings.Add(mapping); Db.SaveChanges(); return(mapping); }
/// <summary> /// Updates a feature group by replacing the enabled features and group members with new collections. /// Members that are effectively removed from the group are assigned to the default group. /// </summary> /// <exception cref="ArgumentNullException">Arguments are null</exception> /// <exception cref="ArgumentException">The new group name is already in use</exception> /// <exception cref="ResourceNotFoundException{Feature}">There is no feature with the specified ID</exception> /// <exception cref="ResourceNotFoundException{FeatureGroup}">There is no group with the specified ID</exception> /// <exception cref="InvalidOperationException">Tried to rename a protected feature group or tried to move users to the public group</exception> public void UpdateGroup(int groupId, FeatureGroupArgs args) { if (args == null) { throw new ArgumentNullException(nameof(args)); } if (Db.FeatureGroups.Any(g => g.Name == args.Name && g.Id != groupId)) { throw new ArgumentException($"A feature group with name '{args.Name}' already exists"); } var group = GetGroup(groupId, loadMembers: true, loadFeatures: true); if (group == null) { throw new ResourceNotFoundException <FeatureGroup>(groupId); } if (group.IsProtected && args.Name != group.Name) { throw new InvalidOperationException($"Protected group '{group.Name}' cannot be renamed"); } if (group.Id == PublicGroup.Id && (args.Members?.Count ?? 0) > 0) { throw new InvalidOperationException("Users cannot explicitly be moved into the public group"); } group.Name = args.Name; var newMembers = GetOrCreateUsers(args.Members).ToList(); var newFeatures = GetFeatures(args.EnabledFeatures, loadGroups: true); // remove old members foreach (var user in group.Members.ToList()) { MoveUserToGroupCore(user, DefaultGroup); } // add new members foreach (var user in newMembers) { MoveUserToGroupCore(user, group); } // remove old enabled features // (for EF to work, we have to make sure not to delete & re-add the same mapping) var featuresToRemove = group.EnabledFeatures.Where(m => !newFeatures.Any(f => f.Id == m.FeatureId)).ToList(); var featuresToAdd = newFeatures.Where(f => !group.EnabledFeatures.Any(m => m.FeatureId == f.Id)).ToList(); foreach (var mapping in featuresToRemove) { Db.FeatureToFeatureGroupMappings.Remove(mapping); } // add new enabled features foreach (var feature in featuresToAdd) { var mapping = new FeatureToFeatureGroupMapping(feature, group); feature.GroupsWhereEnabled.Add(mapping); group.EnabledFeatures.Add(mapping); } Db.SaveChanges(); }