diff --git a/Disco.BI/Disco.BI.csproj b/Disco.BI/Disco.BI.csproj index 9ce88965..7f9ab92e 100644 --- a/Disco.BI/Disco.BI.csproj +++ b/Disco.BI/Disco.BI.csproj @@ -174,11 +174,6 @@ - - - - - @@ -248,7 +243,7 @@ - + diff --git a/Disco.Data/Configuration/SystemConfiguration.cs b/Disco.Data/Configuration/SystemConfiguration.cs index dff88ca9..8a327d64 100644 --- a/Disco.Data/Configuration/SystemConfiguration.cs +++ b/Disco.Data/Configuration/SystemConfiguration.cs @@ -103,6 +103,18 @@ namespace Disco.Data.Configuration } } + public string Administrators + { + get + { + return this.Get("Domain Admins,Disco Admins"); + } + set + { + Set(value); + } + } + #region Plugin Locations public string PluginsLocation { diff --git a/Disco.Services/Authorization/AuthorizationLog.cs b/Disco.Services/Authorization/AuthorizationLog.cs index e9400fd0..71c669b5 100644 --- a/Disco.Services/Authorization/AuthorizationLog.cs +++ b/Disco.Services/Authorization/AuthorizationLog.cs @@ -137,6 +137,16 @@ namespace Disco.Services.Authorization var subjects = string.Join("; ", SubjectsRemoved); Log(EventTypeIds.RoleConfiguredSubjectsRemoved, Role.Id, Role.Name, UserId, subjects); } + public static void LogAdministratorSubjectsAdded(string UserId, IEnumerable SubjectsAdded) + { + var subjects = string.Join("; ", SubjectsAdded); + Log(EventTypeIds.RoleConfiguredSubjectsAdded, -1, "Disco Administrators", UserId, subjects); + } + public static void LogAdministratorSubjectsRemoved(string UserId, IEnumerable SubjectsRemoved) + { + var subjects = string.Join("; ", SubjectsRemoved); + Log(EventTypeIds.RoleConfiguredSubjectsRemoved, -1, "Disco Administrators", UserId, subjects); + } public static void LogRoleConfiguredClaimsAdded(AuthorizationRole Role, string UserId, IEnumerable ClaimsAdded) { var claims = string.Join("; ", ClaimsAdded); diff --git a/Disco.Services/Authorization/Roles/RoleCache.cs b/Disco.Services/Authorization/Roles/RoleCache.cs index b06091dc..c5d2cf72 100644 --- a/Disco.Services/Authorization/Roles/RoleCache.cs +++ b/Disco.Services/Authorization/Roles/RoleCache.cs @@ -14,28 +14,30 @@ namespace Disco.Services.Authorization.Roles { internal const int AdministratorsTokenId = -1; internal const int ComputerAccountTokenId = -200; - internal const string AdministratorsTokenSubjectIds = "Domain Admins,Disco Admins"; internal const string ClaimsJsonEmpty = "null"; + internal static readonly string[] _RequiredAdministratorSubjectIds = new string[] { "Domain Admins" }; private static List _Cache; + private static RoleToken _AdministratorToken; internal static void Initialize(DiscoDataContext Database) { _Cache = Database.AuthorizationRoles.ToList().Select(ar => RoleToken.FromAuthorizationRole(ar)).ToList(); // Add System Roles - AddSystemRoles(); + AddSystemRoles(Database); } - private static void AddSystemRoles() + private static void AddSystemRoles(DiscoDataContext Database) { // Disco Administrators - _Cache.Add(RoleToken.FromAuthorizationRole(new AuthorizationRole() + _AdministratorToken = RoleToken.FromAuthorizationRole(new AuthorizationRole() { Id = AdministratorsTokenId, Name = "Disco Administrators", - SubjectIds = AdministratorsTokenSubjectIds - }, Claims.AdministratorClaims())); + SubjectIds = string.Join(",", GenerateAdministratorSubjectIds(Database)) + }, Claims.AdministratorClaims()); + _Cache.Add(_AdministratorToken); // Computer Accounts _Cache.Add(RoleToken.FromAuthorizationRole(new AuthorizationRole() @@ -45,6 +47,52 @@ namespace Disco.Services.Authorization.Roles }, Claims.ComputerAccountClaims())); } + private static IEnumerable GenerateAdministratorSubjectIds(DiscoDataContext Database) + { + var domainNetBiosName = Interop.ActiveDirectory.ActiveDirectory.PrimaryDomain.NetBiosName; + var configuredSubjectIds = Database.DiscoConfiguration.Administrators.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Contains(@"\") ? s : string.Format(@"{0}\{1}", domainNetBiosName, s)); + + return RequiredAdministratorSubjectIds + .Concat(configuredSubjectIds) + .Distinct(StringComparer.InvariantCultureIgnoreCase) + .OrderBy(s => s); + } + public static IEnumerable RequiredAdministratorSubjectIds + { + get + { + var domainNetBiosName = Interop.ActiveDirectory.ActiveDirectory.PrimaryDomain.NetBiosName; + return _RequiredAdministratorSubjectIds.Select(s => string.Format(@"{0}\{1}", domainNetBiosName, s)); + } + } + public static IEnumerable AdministratorSubjectIds + { + get + { + return _AdministratorToken.SubjectIds.ToList(); + } + } + + public static void UpdateAdministratorSubjectIds(DiscoDataContext Database, IEnumerable SubjectIds) + { + // Clean + SubjectIds = SubjectIds + .Where(s => !string.IsNullOrWhiteSpace(s)) + .Concat(RequiredAdministratorSubjectIds) + .Distinct(StringComparer.InvariantCultureIgnoreCase) + .OrderBy(s => s); + + var subjectIdsString = string.Join(",", SubjectIds); + + // Update Database + Database.DiscoConfiguration.Administrators = subjectIdsString; + Database.SaveChanges(); + + // Update State + _AdministratorToken.SubjectIds = SubjectIds.ToList(); + _AdministratorToken.SubjectIdHashes = new HashSet(SubjectIds.Select(i => i.ToLower())); + } + /// /// Create a clone of an Authorization Role /// Creates immutable clones to avoid side-effects diff --git a/Disco.Services/Authorization/Roles/RoleToken.cs b/Disco.Services/Authorization/Roles/RoleToken.cs index dd19894f..036a05d3 100644 --- a/Disco.Services/Authorization/Roles/RoleToken.cs +++ b/Disco.Services/Authorization/Roles/RoleToken.cs @@ -11,10 +11,10 @@ namespace Disco.Services.Authorization.Roles { public class RoleToken : IRoleToken { - public AuthorizationRole Role { get; set; } + public AuthorizationRole Role { get; internal set; } internal HashSet SubjectIdHashes { get; set; } - public List SubjectIds { get; set; } - public RoleClaims Claims { get; set; } + public List SubjectIds { get; internal set; } + public RoleClaims Claims { get; internal set; } public static RoleToken FromAuthorizationRole(AuthorizationRole Role) { diff --git a/Disco.Services/Users/UserService.cs b/Disco.Services/Users/UserService.cs index 71f1dca1..0d58d712 100644 --- a/Disco.Services/Users/UserService.cs +++ b/Disco.Services/Users/UserService.cs @@ -137,8 +137,6 @@ namespace Disco.Services.Users return Cache.InvalidateRecord(UserId); } - - public static int CreateAuthorizationRole(DiscoDataContext Database, AuthorizationRole Role) { if (Role == null) @@ -192,6 +190,22 @@ namespace Disco.Services.Users Cache.FlushCache(); } + public static IEnumerable AdministratorSubjectIds + { + get + { + return RoleCache.AdministratorSubjectIds; + } + } + public static void UpdateAdministratorSubjectIds(DiscoDataContext Database, IEnumerable SubjectIds) + { + // Update Database & In-Memory State + RoleCache.UpdateAdministratorSubjectIds(Database, SubjectIds); + + // Flush User Cache + Cache.FlushCache(); + } + internal static IEnumerable SearchUsers(DiscoDataContext Database, string Term) { var adImportedUsers = ActiveDirectory.SearchUserAccounts(Term); diff --git a/Disco.Web/Areas/API/Controllers/AuthorizationRoleController.cs b/Disco.Web/Areas/API/Controllers/AuthorizationRoleController.cs index 134c3e2b..e968971f 100644 --- a/Disco.Web/Areas/API/Controllers/AuthorizationRoleController.cs +++ b/Disco.Web/Areas/API/Controllers/AuthorizationRoleController.cs @@ -7,6 +7,7 @@ using Disco.Services.Interop.ActiveDirectory; using Disco.Services.Users; using Disco.Services.Web; using System; +using System.Collections.Generic; using System.Linq; using System.Web.Mvc; @@ -83,8 +84,8 @@ namespace Disco.Web.Areas.API.Controllers private void UpdateClaims(AuthorizationRole AuthorizationRole, string[] ClaimKeys) { var proposedClaims = Claims.BuildClaims(ClaimKeys); - - var currentToken = RoleToken.FromAuthorizationRole(AuthorizationRole); + + var currentToken = RoleToken.FromAuthorizationRole(AuthorizationRole); var currentClaimKeys = Claims.GetClaimKeys(currentToken.Claims); var removedClaims = currentClaimKeys.Except(ClaimKeys).ToArray(); var addedClaims = ClaimKeys.Except(currentClaimKeys).ToArray(); @@ -113,7 +114,7 @@ namespace Disco.Web.Areas.API.Controllers if (invalidSubjects.Count > 0) throw new ArgumentException(string.Format("Subjects not found: {0}", string.Join(", ", invalidSubjects)), "Subjects"); - var proposedSubjects = subjects.Select(s => s.Item2.SamAccountName).OrderBy(s => s).ToArray(); + var proposedSubjects = subjects.Select(s => s.Item2.NetBiosId).OrderBy(s => s).ToArray(); var currentSubjects = AuthorizationRole.SubjectIds == null ? new string[0] : AuthorizationRole.SubjectIds.Split(','); removedSubjects = currentSubjects.Except(proposedSubjects).ToArray(); addedSubjects = proposedSubjects.Except(currentSubjects).ToArray(); @@ -230,6 +231,41 @@ namespace Disco.Web.Areas.API.Controllers } } + [HttpPost] + public virtual ActionResult UpdateAdministratorSubjects(string[] Subjects, bool redirect = false) + { + string[] proposedSubjects; + string[] removedSubjects = null; + string[] addedSubjects = null; + + // Validate Subjects + if (Subjects == null || Subjects.Length == 0) + throw new ArgumentNullException("Subjects", "At least one Id must be supplied"); + + var subjects = Subjects.Where(s => !string.IsNullOrWhiteSpace(s)).Select(s => s.Trim()).Select(s => new Tuple(s, ActiveDirectory.RetrieveObject(s))).ToList(); + var invalidSubjects = subjects.Where(s => s.Item2 == null).ToList(); + + if (invalidSubjects.Count > 0) + throw new ArgumentException(string.Format("Subjects not found: {0}", string.Join(", ", invalidSubjects)), "Subjects"); + + proposedSubjects = subjects.Select(s => s.Item2.NetBiosId).OrderBy(s => s).ToArray(); + var currentSubjects = UserService.AdministratorSubjectIds; + removedSubjects = currentSubjects.Except(proposedSubjects).ToArray(); + addedSubjects = proposedSubjects.Except(currentSubjects).ToArray(); + + UserService.UpdateAdministratorSubjectIds(Database, proposedSubjects); + + if (removedSubjects != null && removedSubjects.Length > 0) + AuthorizationLog.LogAdministratorSubjectsRemoved(CurrentUser.UserId, removedSubjects); + if (addedSubjects != null && addedSubjects.Length > 0) + AuthorizationLog.LogAdministratorSubjectsAdded(CurrentUser.UserId, addedSubjects); + + if (redirect) + return RedirectToAction(MVC.Config.AuthorizationRole.Index()); + else + return Json("OK"); + } + #endregion public virtual ActionResult SearchSubjects(string term) @@ -245,8 +281,13 @@ namespace Disco.Web.Areas.API.Controllers public virtual ActionResult Subject(string Id) { + if (string.IsNullOrWhiteSpace(Id)) + return Json(null, JsonRequestBehavior.AllowGet); + else if (!Id.Contains(@"\")) + Id = string.Format(@"{0}\{1}", ActiveDirectory.PrimaryDomain.NetBiosName, Id); + var subject = ActiveDirectory.RetrieveObject(Id); - + if (subject == null || !(subject is ActiveDirectoryUserAccount || subject is ActiveDirectoryGroup)) return Json(null, JsonRequestBehavior.AllowGet); else diff --git a/Disco.Web/Areas/Config/Controllers/AuthorizationRoleController.cs b/Disco.Web/Areas/Config/Controllers/AuthorizationRoleController.cs index 0726cc0c..b4b6cf96 100644 --- a/Disco.Web/Areas/Config/Controllers/AuthorizationRoleController.cs +++ b/Disco.Web/Areas/Config/Controllers/AuthorizationRoleController.cs @@ -27,10 +27,10 @@ namespace Disco.Web.Areas.Config.Controllers throw new ArgumentException("Invalid Authorization Role Id"); var token = RoleToken.FromAuthorizationRole(ar); - var subjects = token.SubjectIds == null ? new List() : + var subjects = token.SubjectIds == null ? new List() : token.SubjectIds.Select(subjectId => ActiveDirectory.RetrieveObject(subjectId)) .Where(item => item != null) - .Select(item => Models.AuthorizationRole.ShowModel.SubjectDescriptor.FromActiveDirectoryObject(item)) + .Select(item => Models.AuthorizationRole.SubjectDescriptorModel.FromActiveDirectoryObject(item)) .OrderBy(item => item.Name).ToList(); var m = new Models.AuthorizationRole.ShowModel() @@ -52,9 +52,16 @@ namespace Disco.Web.Areas.Config.Controllers var ars = Database.AuthorizationRoles.ToList() .Select(ar => RoleToken.FromAuthorizationRole(ar)).Cast().ToList(); + var administratorSubjects = UserService.AdministratorSubjectIds + .Select(subjectId => ActiveDirectory.RetrieveObject(subjectId)) + .Where(item => item != null) + .Select(item => Models.AuthorizationRole.SubjectDescriptorModel.FromActiveDirectoryObject(item)) + .OrderBy(item => item.Name).ToList(); + var m = new Models.AuthorizationRole.IndexModel() { - Tokens = ars + Tokens = ars, + AdministratorSubjects = administratorSubjects }; // UI Extensions diff --git a/Disco.Web/Areas/Config/Models/AuthorizationRole/IndexModel.cs b/Disco.Web/Areas/Config/Models/AuthorizationRole/IndexModel.cs index 2746462e..41bfdf62 100644 --- a/Disco.Web/Areas/Config/Models/AuthorizationRole/IndexModel.cs +++ b/Disco.Web/Areas/Config/Models/AuthorizationRole/IndexModel.cs @@ -11,5 +11,6 @@ namespace Disco.Web.Areas.Config.Models.AuthorizationRole public class IndexModel : ConfigAuthorizationRoleIndexModel { public List Tokens { get; set; } + public List AdministratorSubjects { get; set; } } } \ No newline at end of file diff --git a/Disco.Web/Areas/Config/Models/AuthorizationRole/ShowModel.cs b/Disco.Web/Areas/Config/Models/AuthorizationRole/ShowModel.cs index a3da1092..4db7f9aa 100644 --- a/Disco.Web/Areas/Config/Models/AuthorizationRole/ShowModel.cs +++ b/Disco.Web/Areas/Config/Models/AuthorizationRole/ShowModel.cs @@ -13,7 +13,7 @@ namespace Disco.Web.Areas.Config.Models.AuthorizationRole { public IRoleToken Token { get; set; } - public List Subjects { get; set; } + public List Subjects { get; set; } public IClaimNavigatorItem ClaimNavigator { get; set; } @@ -29,26 +29,5 @@ namespace Disco.Web.Areas.Config.Models.AuthorizationRole }; } } - - public class SubjectDescriptor - { - public bool IsGroup { get; set; } - public string Name { get; set; } - public string Id { get; set; } - - public static SubjectDescriptor FromActiveDirectoryObject(IActiveDirectoryObject ADObject) - { - var item = new SubjectDescriptor() - { - Id = ADObject.NetBiosId, - Name = ADObject.Name - }; - - if (ADObject is ActiveDirectoryGroup) - item.IsGroup = true; - - return item; - } - } } } \ No newline at end of file diff --git a/Disco.Web/Areas/Config/Models/AuthorizationRole/SubjectDescriptorModel.cs b/Disco.Web/Areas/Config/Models/AuthorizationRole/SubjectDescriptorModel.cs new file mode 100644 index 00000000..b8d1481e --- /dev/null +++ b/Disco.Web/Areas/Config/Models/AuthorizationRole/SubjectDescriptorModel.cs @@ -0,0 +1,25 @@ +using Disco.Models.Interop.ActiveDirectory; + +namespace Disco.Web.Areas.Config.Models.AuthorizationRole +{ + public class SubjectDescriptorModel + { + public bool IsGroup { get; set; } + public string Name { get; set; } + public string Id { get; set; } + + public static SubjectDescriptorModel FromActiveDirectoryObject(IActiveDirectoryObject ADObject) + { + var item = new SubjectDescriptorModel() + { + Id = ADObject.NetBiosId, + Name = ADObject.DisplayName + }; + + if (ADObject is ActiveDirectoryGroup) + item.IsGroup = true; + + return item; + } + } +} \ No newline at end of file diff --git a/Disco.Web/Areas/Config/Views/AuthorizationRole/Index.cshtml b/Disco.Web/Areas/Config/Views/AuthorizationRole/Index.cshtml index 759aea3b..4550a0c0 100644 --- a/Disco.Web/Areas/Config/Views/AuthorizationRole/Index.cshtml +++ b/Disco.Web/Areas/Config/Views/AuthorizationRole/Index.cshtml @@ -38,6 +38,184 @@ else } } -
- @Html.ActionLinkButton("Create Authorization Role", MVC.Config.AuthorizationRole.Create()) + +
+
+ None Associated +
    + @foreach (var sg in Model.AdministratorSubjects) + { + var displayName = sg.Id == sg.Name ? sg.Id : string.Format("{0} [{1}]", sg.Name, sg.Id); +
  • @if (sg.IsGroup) + { + @displayName + } + else + { + @displayName + }
  • + } +
+
+
+ + Add +
+
+ + +
+ Update Disco Administrators [@Model.AdministratorSubjects.Count] + @Html.ActionLinkButton("Create Authorization Role", MVC.Config.AuthorizationRole.Create()) +
\ No newline at end of file diff --git a/Disco.Web/Areas/Config/Views/AuthorizationRole/Index.generated.cs b/Disco.Web/Areas/Config/Views/AuthorizationRole/Index.generated.cs index 010e3849..93c07df4 100644 --- a/Disco.Web/Areas/Config/Views/AuthorizationRole/Index.generated.cs +++ b/Disco.Web/Areas/Config/Views/AuthorizationRole/Index.generated.cs @@ -2,7 +2,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34011 +// Runtime Version:4.0.30319.34014 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -176,22 +176,315 @@ WriteLiteral(" \r\n"); #line default #line hidden -WriteLiteral("\r\n\r\n \r\n None Associated\r\n \r\n"); + + + #line 46 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + + + #line default + #line hidden + + #line 46 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + foreach (var sg in Model.AdministratorSubjects) + { + var displayName = sg.Id == sg.Name ? sg.Id : string.Format("{0} [{1}]", sg.Name, sg.Id); + + + #line default + #line hidden +WriteLiteral(" (sg.IsGroup ? "group" : "user" + + #line default + #line hidden +, 1813), false) +); + +WriteLiteral(" data-subjectid=\""); + + + #line 49 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + Write(sg.Id); + + + #line default + #line hidden +WriteLiteral("\""); + +WriteLiteral(">"); + + + #line 49 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + if (sg.IsGroup) + { + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 51 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + + + #line default + #line hidden + + #line 51 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + Write(displayName); + + + #line default + #line hidden + + #line 51 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + + } + else + { + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 55 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + + + #line default + #line hidden + + #line 55 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + Write(displayName); + + + #line default + #line hidden + + #line 55 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + + } + + #line default + #line hidden +WriteLiteral("\r\n"); + + + #line 57 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n
\r\n \r\n \r\n Add\r\n \r\n (Url.Action(MVC.API.AuthorizationRole.UpdateAdministratorSubjects(null, true)) + + #line default + #line hidden +, 2885), false) +); + +WriteLiteral(" method=\"post\""); + +WriteLiteral(@"> + +\r\n\r\n\r\n"); +WriteLiteral(">\r\n Update Disco Administrators ["); + + + #line 219 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + Write(Model.AdministratorSubjects.Count); + + + #line default + #line hidden +WriteLiteral("]\r\n"); WriteLiteral(" "); - #line 42 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" + #line 220 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml" Write(Html.ActionLinkButton("Create Authorization Role", MVC.Config.AuthorizationRole.Create())); #line default #line hidden -WriteLiteral("\r\n\r\n"); +WriteLiteral("\r\n"); } } diff --git a/Disco.Web/Areas/Config/Views/AuthorizationRole/Show.cshtml b/Disco.Web/Areas/Config/Views/AuthorizationRole/Show.cshtml index cd048b63..1d61e35b 100644 --- a/Disco.Web/Areas/Config/Views/AuthorizationRole/Show.cshtml +++ b/Disco.Web/Areas/Config/Views/AuthorizationRole/Show.cshtml @@ -166,12 +166,11 @@ } function add(){ - var id = textAdd.val(); $.ajax({ url: '@Url.Action(MVC.API.AuthorizationRole.Subject())', - method: 'get', + method: 'post', data: { Id: id } }).done(function(response){ if (response){ diff --git a/Disco.Web/Areas/Config/Views/AuthorizationRole/Show.generated.cs b/Disco.Web/Areas/Config/Views/AuthorizationRole/Show.generated.cs index 22c80abc..926d26ed 100644 --- a/Disco.Web/Areas/Config/Views/AuthorizationRole/Show.generated.cs +++ b/Disco.Web/Areas/Config/Views/AuthorizationRole/Show.generated.cs @@ -2,7 +2,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34011 +// Runtime Version:4.0.30319.34014 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -538,63 +538,63 @@ WriteLiteral("\',\r\n minLength: 2,\r " }else{\r\n $this.attr(\'data-subjectstatus\', \'r" + "emoved\').hide();\r\n }\r\n\r\n " + " updateNoSubjects();\r\n }\r\n\r\n " + -" function add(){\r\n \r\n " + -" var id = textAdd.val();\r\n\r\n $.ajax({\r" + -"\n url: \'"); +" function add(){\r\n var id = textAdd.val()" + +";\r\n\r\n $.ajax({\r\n " + +" url: \'"); - #line 173 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml" + #line 172 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml" Write(Url.Action(MVC.API.AuthorizationRole.Subject())); #line default #line hidden -WriteLiteral("\',\r\n method: \'get\',\r\n " + -" data: { Id: id }\r\n }).done(function(re" + -"sponse){\r\n if (response){\r\n " + -" if (list.find(\'li[data-subjectid=\"\'+response.Id+\'\"]\').leng" + -"th == 0){\r\n \r\n " + -" var liIcon = $(\'\').addClass(\'fa fa-lg\');\r\n " + -" if (response.Type === \'user\')\r\n " + -" liIcon.addClass(\'fa-user\');\r\n " + -" else\r\n liIc" + -"on.addClass(\'fa-users\');\r\n\r\n var li =" + -" $(\'
  • \')\r\n .append(liIcon)\r\n " + -" .append($(\'\').text(response.I" + -"d == response.Name ? response.Id : response.Name + \' [\' + response.Id + \']\'))\r\n" + -" .append($(\'\').addClass(\'fa fa" + -"-times-circle remove\'))\r\n .addCla" + -"ss(response.Type)\r\n .attr(\'data-s" + -"ubjectid\', response.Id)\r\n .attr(\'" + -"data-subjectstatus\', \'new\');\r\n\r\n list" + -".append(li);\r\n\r\n updateNoSubjects(); " + -" \r\n " + -" }else{\r\n alert(\'That subject has alr" + -"eady been added\');\r\n }\r\n " + -" }else{\r\n alert(\'Unknow" + -"n Id\');\r\n }\r\n " + -"}).fail(function(jqXHR, textStatus, errorThrown){\r\n " + -" alert(\'Error: \' + errorThrown);\r\n });\r\n " + -" }\r\n\r\n function updateNoS" + -"ubjects(){\r\n if (list.find(\'li:visible\').length >" + -" 0)\r\n noSubjects.hide();\r\n " + -" else\r\n noSubjects.show();\r\n " + -" }\r\n\r\n function saveChanges(){\r" + -"\n var form = $(\'#Config_AuthRoles_Subjects_Update" + -"_Dialog_Form\').empty();\r\n\r\n list.find(\'li[data-su" + -"bjectstatus!=\"removed\"]\').each(function(){\r\n " + -"var subjectId = $(this).attr(\'data-subjectid\');\r\n " + -" \r\n form.append($(\'\').attr({\r\n " + -" \'name\': \'Subjects\',\r\n " + -" \'type\': \'hidden\'\r\n }).val(su" + -"bjectId));\r\n\r\n }).get();\r\n\r\n " + -" form.submit();\r\n\r\n dialog.dialog(\"disa" + -"ble\");\r\n dialog.dialog(\"option\", \"buttons\", null)" + -";\r\n }\r\n\r\n $(function(){\r\n " + -" $(\'#Config_AuthRoles_Subjects_Update\').click(show" + -"Dialog);\r\n });\r\n\r\n })();\r\n " + -" \r\n \r\n \r\n \r\n \r\n \').addClass(\'fa fa-lg\');\r\n " + +" if (response.Type === \'user\')\r\n " + +" liIcon.addClass(\'fa-user\');\r\n " + +" else\r\n liI" + +"con.addClass(\'fa-users\');\r\n\r\n var li " + +"= $(\'
  • \')\r\n .append(liIcon)\r\n " + +" .append($(\'\').text(response." + +"Id == response.Name ? response.Id : response.Name + \' [\' + response.Id + \']\'))\r" + +"\n .append($(\'\').addClass(\'fa f" + +"a-times-circle remove\'))\r\n .addCl" + +"ass(response.Type)\r\n .attr(\'data-" + +"subjectid\', response.Id)\r\n .attr(" + +"\'data-subjectstatus\', \'new\');\r\n\r\n lis" + +"t.append(li);\r\n\r\n updateNoSubjects();" + +" \r\n " + +" }else{\r\n alert(\'That subject has al" + +"ready been added\');\r\n }\r\n " + +" }else{\r\n alert(\'Unkno" + +"wn Id\');\r\n }\r\n " + +" }).fail(function(jqXHR, textStatus, errorThrown){\r\n " + +" alert(\'Error: \' + errorThrown);\r\n });\r\n " + +" }\r\n\r\n function updateNo" + +"Subjects(){\r\n if (list.find(\'li:visible\').length " + +"> 0)\r\n noSubjects.hide();\r\n " + +" else\r\n noSubjects.show();\r\n " + +" }\r\n\r\n function saveChanges(){" + +"\r\n var form = $(\'#Config_AuthRoles_Subjects_Updat" + +"e_Dialog_Form\').empty();\r\n\r\n list.find(\'li[data-s" + +"ubjectstatus!=\"removed\"]\').each(function(){\r\n " + +" var subjectId = $(this).attr(\'data-subjectid\');\r\n " + +" \r\n form.append($(\'\').attr({\r\n " + +" \'name\': \'Subjects\',\r\n " + +" \'type\': \'hidden\'\r\n }).val(s" + +"ubjectId));\r\n\r\n }).get();\r\n\r\n " + +" form.submit();\r\n\r\n dialog.dialog(\"dis" + +"able\");\r\n dialog.dialog(\"option\", \"buttons\", null" + +");\r\n }\r\n\r\n $(function(){\r\n" + +" $(\'#Config_AuthRoles_Subjects_Update\').click(sho" + +"wDialog);\r\n });\r\n\r\n })();\r\n " + +" \r\n \r\n \r\n <" + +"/tr>\r\n \r\n Save Changes"); - #line 248 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml" + #line 247 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml" Write(AjaxHelpers.AjaxLoader()); @@ -623,7 +623,7 @@ WriteLiteral("\r\n \r\n