Update #43: Disco Administrators are configurable

This commit is contained in:
Gary Sharp
2014-04-11 19:57:51 +10:00
parent e984221c95
commit 41dc002ef8
17 changed files with 742 additions and 111 deletions
+1 -6
View File
@@ -174,11 +174,6 @@
<Compile Include="BI\DocumentTemplateBI\Importer\DocumentImporterJob.cs" />
<Compile Include="BI\DocumentTemplateBI\Importer\DocumentImporterCleanCacheJob.cs" />
<Compile Include="BI\DocumentTemplateBI\Importer\DocumentImporterLog.cs" />
<Compile Include="BI\Interop\ActiveDirectory\ActiveDirectory.cs" />
<Compile Include="BI\Interop\ActiveDirectory\ActiveDirectoryHelpers.cs" />
<Compile Include="BI\Interop\ActiveDirectory\ActiveDirectoryOrganisationalUnit.cs" />
<Compile Include="BI\Interop\ActiveDirectory\ActiveDirectoryUpdateLastNetworkLogonDateJob.cs" />
<Compile Include="BI\Interop\ActiveDirectory\ActiveDirectoryUserAccountExtensions.cs" />
<Compile Include="BI\Expressions\ExpressionCache.cs" />
<Compile Include="BI\Interop\Community\UpdateCheck.cs" />
<Compile Include="BI\Interop\Community\UpdateCheckTask.cs" />
@@ -248,7 +243,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties BuildVersion_UpdateFileVersion="True" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.DeltaBaseYear.MonthAndDayStamp.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_DetectChanges="False" BuildVersion_BuildAction="Both" BuildVersion_StartDate="2011/7/1" />
<UserProperties BuildVersion_StartDate="2011/7/1" BuildVersion_BuildAction="Both" BuildVersion_DetectChanges="False" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.DeltaBaseYear.MonthAndDayStamp.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" />
</VisualStudio>
</ProjectExtensions>
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
@@ -103,6 +103,18 @@ namespace Disco.Data.Configuration
}
}
public string Administrators
{
get
{
return this.Get<string>("Domain Admins,Disco Admins");
}
set
{
Set(value);
}
}
#region Plugin Locations
public string PluginsLocation
{
@@ -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<string> SubjectsAdded)
{
var subjects = string.Join("; ", SubjectsAdded);
Log(EventTypeIds.RoleConfiguredSubjectsAdded, -1, "Disco Administrators", UserId, subjects);
}
public static void LogAdministratorSubjectsRemoved(string UserId, IEnumerable<string> SubjectsRemoved)
{
var subjects = string.Join("; ", SubjectsRemoved);
Log(EventTypeIds.RoleConfiguredSubjectsRemoved, -1, "Disco Administrators", UserId, subjects);
}
public static void LogRoleConfiguredClaimsAdded(AuthorizationRole Role, string UserId, IEnumerable<string> ClaimsAdded)
{
var claims = string.Join("; ", ClaimsAdded);
@@ -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<RoleToken> _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<string> 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<string> RequiredAdministratorSubjectIds
{
get
{
var domainNetBiosName = Interop.ActiveDirectory.ActiveDirectory.PrimaryDomain.NetBiosName;
return _RequiredAdministratorSubjectIds.Select(s => string.Format(@"{0}\{1}", domainNetBiosName, s));
}
}
public static IEnumerable<string> AdministratorSubjectIds
{
get
{
return _AdministratorToken.SubjectIds.ToList();
}
}
public static void UpdateAdministratorSubjectIds(DiscoDataContext Database, IEnumerable<string> 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<string>(SubjectIds.Select(i => i.ToLower()));
}
/// <summary>
/// Create a clone of an Authorization Role
/// <para>Creates immutable clones to avoid side-effects</para>
@@ -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<string> SubjectIdHashes { get; set; }
public List<string> SubjectIds { get; set; }
public RoleClaims Claims { get; set; }
public List<string> SubjectIds { get; internal set; }
public RoleClaims Claims { get; internal set; }
public static RoleToken FromAuthorizationRole(AuthorizationRole Role)
{
+16 -2
View File
@@ -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<string> AdministratorSubjectIds
{
get
{
return RoleCache.AdministratorSubjectIds;
}
}
public static void UpdateAdministratorSubjectIds(DiscoDataContext Database, IEnumerable<string> SubjectIds)
{
// Update Database & In-Memory State
RoleCache.UpdateAdministratorSubjectIds(Database, SubjectIds);
// Flush User Cache
Cache.FlushCache();
}
internal static IEnumerable<ActiveDirectoryUserAccount> SearchUsers(DiscoDataContext Database, string Term)
{
var adImportedUsers = ActiveDirectory.SearchUserAccounts(Term);
@@ -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;
@@ -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<string, IActiveDirectoryObject>(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,6 +281,11 @@ 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))
@@ -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<Models.AuthorizationRole.ShowModel.SubjectDescriptor>() :
var subjects = token.SubjectIds == null ? new List<Models.AuthorizationRole.SubjectDescriptorModel>() :
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<IRoleToken>().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
@@ -11,5 +11,6 @@ namespace Disco.Web.Areas.Config.Models.AuthorizationRole
public class IndexModel : ConfigAuthorizationRoleIndexModel
{
public List<IRoleToken> Tokens { get; set; }
public List<SubjectDescriptorModel> AdministratorSubjects { get; set; }
}
}
@@ -13,7 +13,7 @@ namespace Disco.Web.Areas.Config.Models.AuthorizationRole
{
public IRoleToken Token { get; set; }
public List<SubjectDescriptor> Subjects { get; set; }
public List<SubjectDescriptorModel> 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;
}
}
}
}
@@ -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;
}
}
}
@@ -38,6 +38,184 @@ else
}
</table>
}
<!-- #region Administrator Subjects -->
<div id="Config_AuthRoles_Subjects_Update_Dialog" class="dialog" title="Disco Administrators">
<div id="Config_AuthRoles_Subjects_Update_Dialog_ListContainer">
<span id="Config_AuthRoles_Subjects_Update_Dialog_None" class="smallMessage">None Associated</span>
<ul id="Config_AuthRoles_Subjects_Update_Dialog_List" class="none">
@foreach (var sg in Model.AdministratorSubjects)
{
var displayName = sg.Id == sg.Name ? sg.Id : string.Format("{0} [{1}]", sg.Name, sg.Id);
<li class="@(sg.IsGroup ? "group" : "user")" data-subjectid="@sg.Id">@if (sg.IsGroup)
{
<i class="fa fa-users fa-lg"></i>@displayName
}
else
{
<i class="fa fa-user fa-lg"></i>@displayName
}<i class="fa fa-times-circle remove"></i></li>
}
</ul>
</div>
<div id="Config_AuthRoles_Subjects_Update_Dialog_AddContainer">
<input type="text" id="Config_AuthRoles_Subjects_Update_Dialog_TextAdd" />
<a id="Config_AuthRoles_Subjects_Update_Dialog_Add" href="#" class="button small">Add</a>
</div>
<form id="Config_AuthRoles_Subjects_Update_Dialog_Form" action="@(Url.Action(MVC.API.AuthorizationRole.UpdateAdministratorSubjects(null, true)))" method="post"></form>
</div>
<script>
(function () {
var dialog, textAdd, list, noSubjects, form;
function showDialog() {
if (!dialog) {
dialog = $('#Config_AuthRoles_Subjects_Update_Dialog').dialog({
resizable: false,
modal: true,
autoOpen: false,
width: 350,
height: 420,
buttons: {
"Save Changes": saveChanges,
Cancel: cancel
}
});
dialog.on('click', '.remove', remove);
list = $('#Config_AuthRoles_Subjects_Update_Dialog_List');
noSubjects = $('#Config_AuthRoles_Subjects_Update_Dialog_None');
textAdd = $('#Config_AuthRoles_Subjects_Update_Dialog_TextAdd');
textAdd.watermark('Search Subjects')
.autocomplete({
source: '@(Url.Action(MVC.API.AuthorizationRole.SearchSubjects()))',
minLength: 2,
focus: function (e, ui) {
textAdd.val(ui.item.Id);
return false;
},
select: function (e, ui) {
textAdd.val(ui.item.Id).blur();
return false;
}
}).data('ui-autocomplete')._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a><strong>" + item.Name + "</strong><br>" + item.Id + " (" + item.Type + ")</a>")
.appendTo(ul);
};
$('#Config_AuthRoles_Subjects_Update_Dialog_Add').click(add);
}
dialog.dialog('open');
updateNoSubjects();
return false;
}
function cancel() {
$(this).dialog("close");
list.find('li').each(function () {
$this = $(this);
if ($this.is('[data-subjectstatus="new"]')) {
$this.remove();
} else {
if ($this.is('[data-subjectstatus="removed"]')) {
$this.show();
}
}
});
}
function remove() {
$this = $(this).closest('li');
if ($this.is('[data-subjectstatus="new"]')) {
$this.remove();
} else {
$this.attr('data-subjectstatus', 'removed').hide();
}
updateNoSubjects();
}
function add() {
var id = textAdd.val();
$.ajax({
url: '@Url.Action(MVC.API.AuthorizationRole.Subject())',
method: 'post',
data: { Id: id }
}).done(function (response) {
if (response) {
if (list.find('li[data-subjectid="' + response.Id + '"]').length == 0) {
var liIcon = $('<i>').addClass('fa fa-lg');
if (response.Type === 'user')
liIcon.addClass('fa-user');
else
liIcon.addClass('fa-users');
var li = $('<li>')
.append(liIcon)
.append($('<span>').text(response.Id == response.Name ? response.Id : response.Name + ' [' + response.Id + ']'))
.append($('<i>').addClass('fa fa-times-circle remove'))
.addClass(response.Type)
.attr('data-subjectid', response.Id)
.attr('data-subjectstatus', 'new');
list.append(li);
updateNoSubjects();
} else {
alert('That subject has already been added');
}
} else {
alert('Unknown Id');
}
}).fail(function (jqXHR, textStatus, errorThrown) {
alert('Error: ' + errorThrown);
});
}
function updateNoSubjects() {
if (list.find('li:visible').length > 0)
noSubjects.hide();
else
noSubjects.show();
}
function saveChanges() {
var form = $('#Config_AuthRoles_Subjects_Update_Dialog_Form').empty();
list.find('li[data-subjectstatus!="removed"]').each(function () {
var subjectId = $(this).attr('data-subjectid');
form.append($('<input>').attr({
'name': 'Subjects',
'type': 'hidden'
}).val(subjectId));
}).get();
form.submit();
dialog.dialog("disable");
dialog.dialog("option", "buttons", null);
}
$(function () {
$('#Config_AuthRoles_UpdateAdministrators').click(showDialog);
});
})();
</script>
<!-- #endregion -->
<div class="actionBar">
<a id="Config_AuthRoles_UpdateAdministrators" href="#" class="button">Update Disco Administrators [@Model.AdministratorSubjects.Count]</a>
@Html.ActionLinkButton("Create Authorization Role", MVC.Config.AuthorizationRole.Create())
</div>
@@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 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(" </table>\r\n");
#line default
#line hidden
WriteLiteral("<div");
WriteLiteral("<!-- #region Administrator Subjects -->\r\n<div");
WriteLiteral(" id=\"Config_AuthRoles_Subjects_Update_Dialog\"");
WriteLiteral(" class=\"dialog\"");
WriteLiteral(" title=\"Disco Administrators\"");
WriteLiteral(">\r\n <div");
WriteLiteral(" id=\"Config_AuthRoles_Subjects_Update_Dialog_ListContainer\"");
WriteLiteral(">\r\n <span");
WriteLiteral(" id=\"Config_AuthRoles_Subjects_Update_Dialog_None\"");
WriteLiteral(" class=\"smallMessage\"");
WriteLiteral(">None Associated</span>\r\n <ul");
WriteLiteral(" id=\"Config_AuthRoles_Subjects_Update_Dialog_List\"");
WriteLiteral(" class=\"none\"");
WriteLiteral(">\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(" <li");
WriteAttribute("class", Tuple.Create(" class=\"", 1805), Tuple.Create("\"", 1845)
#line 49 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml"
, Tuple.Create(Tuple.Create("", 1813), Tuple.Create<System.Object, System.Int32>(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(" <i");
WriteLiteral(" class=\"fa fa-users fa-lg\"");
WriteLiteral("></i>");
#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(" <i");
WriteLiteral(" class=\"fa fa-user fa-lg\"");
WriteLiteral("></i>");
#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("<i");
WriteLiteral(" class=\"fa fa-times-circle remove\"");
WriteLiteral("></i></li>\r\n");
#line 57 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml"
}
#line default
#line hidden
WriteLiteral(" </ul>\r\n </div>\r\n <div");
WriteLiteral(" id=\"Config_AuthRoles_Subjects_Update_Dialog_AddContainer\"");
WriteLiteral(">\r\n <input");
WriteLiteral(" type=\"text\"");
WriteLiteral(" id=\"Config_AuthRoles_Subjects_Update_Dialog_TextAdd\"");
WriteLiteral(" />\r\n <a");
WriteLiteral(" id=\"Config_AuthRoles_Subjects_Update_Dialog_Add\"");
WriteLiteral(" href=\"#\"");
WriteLiteral(" class=\"button small\"");
WriteLiteral(">Add</a>\r\n </div>\r\n <form");
WriteLiteral(" id=\"Config_AuthRoles_Subjects_Update_Dialog_Form\"");
WriteAttribute("action", Tuple.Create(" action=\"", 2876), Tuple.Create("\"", 2965)
#line 64 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml"
, Tuple.Create(Tuple.Create("", 2885), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.AuthorizationRole.UpdateAdministratorSubjects(null, true))
#line default
#line hidden
, 2885), false)
);
WriteLiteral(" method=\"post\"");
WriteLiteral(@"></form>
</div>
<script>
(function () {
var dialog, textAdd, list, noSubjects, form;
function showDialog() {
if (!dialog) {
dialog = $('#Config_AuthRoles_Subjects_Update_Dialog').dialog({
resizable: false,
modal: true,
autoOpen: false,
width: 350,
height: 420,
buttons: {
""Save Changes"": saveChanges,
Cancel: cancel
}
});
dialog.on('click', '.remove', remove);
list = $('#Config_AuthRoles_Subjects_Update_Dialog_List');
noSubjects = $('#Config_AuthRoles_Subjects_Update_Dialog_None');
textAdd = $('#Config_AuthRoles_Subjects_Update_Dialog_TextAdd');
textAdd.watermark('Search Subjects')
.autocomplete({
source: '");
#line 93 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml"
Write(Url.Action(MVC.API.AuthorizationRole.SearchSubjects()));
#line default
#line hidden
WriteLiteral("\',\r\n minLength: 2,\r\n focus: functio" +
"n (e, ui) {\r\n textAdd.val(ui.item.Id);\r\n " +
" return false;\r\n },\r\n " +
" select: function (e, ui) {\r\n textAdd.val(ui.item.Id" +
").blur();\r\n return false;\r\n }\r" +
"\n }).data(\'ui-autocomplete\')._renderItem = function (ul, item" +
") {\r\n return $(\"<li></li>\")\r\n " +
".data(\"item.autocomplete\", item)\r\n .append(\"<a><stron" +
"g>\" + item.Name + \"</strong><br>\" + item.Id + \" (\" + item.Type + \")</a>\")\r\n " +
" .appendTo(ul);\r\n };\r\n\r\n " +
" $(\'#Config_AuthRoles_Subjects_Update_Dialog_Add\').click(add);\r\n }\r\n\r" +
"\n dialog.dialog(\'open\');\r\n\r\n updateNoSubjects();\r\n " +
" return false;\r\n }\r\n\r\n function cancel() {\r\n $(this)" +
".dialog(\"close\");\r\n\r\n list.find(\'li\').each(function () {\r\n " +
" $this = $(this);\r\n if ($this.is(\'[data-subjectstatus=\"new\"]\'" +
")) {\r\n $this.remove();\r\n } else {\r\n " +
" if ($this.is(\'[data-subjectstatus=\"removed\"]\')) {\r\n " +
" $this.show();\r\n }\r\n }\r\n });\r\n " +
" }\r\n\r\n function remove() {\r\n $this = $(this).closest(\'li\'" +
");\r\n\r\n if ($this.is(\'[data-subjectstatus=\"new\"]\')) {\r\n " +
" $this.remove();\r\n } else {\r\n $this.attr(\'data-subject" +
"status\', \'removed\').hide();\r\n }\r\n\r\n updateNoSubjects();\r\n " +
" }\r\n\r\n function add() {\r\n var id = textAdd.val();\r\n\r\n " +
" $.ajax({\r\n url: \'");
#line 150 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml"
Write(Url.Action(MVC.API.AuthorizationRole.Subject()));
#line default
#line hidden
WriteLiteral("\',\r\n method: \'post\',\r\n data: { Id: id }\r\n " +
" }).done(function (response) {\r\n if (response) {\r\n " +
" if (list.find(\'li[data-subjectid=\"\' + response.Id + \'\"]\').length == 0) {\r\n" +
"\r\n var liIcon = $(\'<i>\').addClass(\'fa fa-lg\');\r\n " +
" if (response.Type === \'user\')\r\n liIcon" +
".addClass(\'fa-user\');\r\n else\r\n " +
" liIcon.addClass(\'fa-users\');\r\n\r\n var li = $(\'<li>\')\r\n " +
" .append(liIcon)\r\n .append($(" +
"\'<span>\').text(response.Id == response.Name ? response.Id : response.Name + \' [\'" +
" + response.Id + \']\'))\r\n .append($(\'<i>\').addClass(\'f" +
"a fa-times-circle remove\'))\r\n .addClass(response.Type" +
")\r\n .attr(\'data-subjectid\', 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 already been adde" +
"d\');\r\n }\r\n } else {\r\n alert" +
"(\'Unknown Id\');\r\n }\r\n }).fail(function (jqXHR, textSta" +
"tus, errorThrown) {\r\n alert(\'Error: \' + errorThrown);\r\n " +
" });\r\n }\r\n\r\n function updateNoSubjects() {\r\n if (l" +
"ist.find(\'li:visible\').length > 0)\r\n noSubjects.hide();\r\n " +
" else\r\n noSubjects.show();\r\n }\r\n\r\n function save" +
"Changes() {\r\n var form = $(\'#Config_AuthRoles_Subjects_Update_Dialog_" +
"Form\').empty();\r\n\r\n list.find(\'li[data-subjectstatus!=\"removed\"]\').ea" +
"ch(function () {\r\n var subjectId = $(this).attr(\'data-subjectid\')" +
";\r\n\r\n form.append($(\'<input>\').attr({\r\n \'name\'" +
": \'Subjects\',\r\n \'type\': \'hidden\'\r\n }).val(subj" +
"ectId));\r\n\r\n }).get();\r\n\r\n form.submit();\r\n\r\n d" +
"ialog.dialog(\"disable\");\r\n dialog.dialog(\"option\", \"buttons\", null);\r" +
"\n }\r\n\r\n $(function () {\r\n $(\'#Config_AuthRoles_UpdateAd" +
"ministrators\').click(showDialog);\r\n });\r\n\r\n })();\r\n</script>\r\n<!-- #en" +
"dregion -->\r\n<div");
WriteLiteral(" class=\"actionBar\"");
WriteLiteral(">\r\n");
WriteLiteral(">\r\n <a");
WriteLiteral(" id=\"Config_AuthRoles_UpdateAdministrators\"");
WriteLiteral(" href=\"#\"");
WriteLiteral(" class=\"button\"");
WriteLiteral(">Update Disco Administrators [");
#line 219 "..\..\Areas\Config\Views\AuthorizationRole\Index.cshtml"
Write(Model.AdministratorSubjects.Count);
#line default
#line hidden
WriteLiteral("]</a>\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</div>\r\n");
WriteLiteral("\r\n</div>");
}
}
@@ -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){
@@ -2,7 +2,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 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 = $(\'<i>\').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 =" +
" $(\'<li>\')\r\n .append(liIcon)\r\n " +
" .append($(\'<span>\').text(response.I" +
"d == response.Name ? response.Id : response.Name + \' [\' + response.Id + \']\'))\r\n" +
" .append($(\'<i>\').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($(\'<input>\').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 " +
" </script>\r\n </div>\r\n </td>\r\n </" +
"tr>\r\n <tr>\r\n <td");
WriteLiteral("\',\r\n method: \'post\',\r\n " +
" data: { Id: id }\r\n }).done(function(r" +
"esponse){\r\n if (response){\r\n " +
" if (list.find(\'li[data-subjectid=\"\'+response.Id+\'\"]\').len" +
"gth == 0){\r\n \r\n " +
" var liIcon = $(\'<i>\').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 " +
"= $(\'<li>\')\r\n .append(liIcon)\r\n " +
" .append($(\'<span>\').text(response." +
"Id == response.Name ? response.Id : response.Name + \' [\' + response.Id + \']\'))\r" +
"\n .append($(\'<i>\').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($(\'<input>\').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 " +
" </script>\r\n </div>\r\n </td>\r\n <" +
"/tr>\r\n <tr>\r\n <td");
WriteLiteral(" colspan=\"2\"");
@@ -613,7 +613,7 @@ WriteLiteral(" class=\"button small disabled\"");
WriteLiteral(">Save Changes</a>");
#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 </div>\r\n <script>\r\n
"(){\r\n var claimNodes = ");
#line 252 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml"
#line 251 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml"
Write(new HtmlString(Newtonsoft.Json.JsonConvert.SerializeObject(Model.ClaimNavigatorFancyTreeNodes)));
@@ -662,7 +662,7 @@ WriteLiteral(@";
url: '");
#line 282 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml"
#line 281 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml"
Write(Url.Action(MVC.API.AuthorizationRole.UpdateClaims(Model.Token.Role.Id)));
@@ -702,7 +702,7 @@ WriteLiteral(">\r\n");
WriteLiteral(" ");
#line 308 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml"
#line 307 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml"
Write(Html.ActionLinkButton("Delete", MVC.API.AuthorizationRole.Delete(Model.Token.Role.Id, true), "Config_AuthRoles_Actions_Delete_Button"));
+2 -1
View File
@@ -203,6 +203,7 @@
<Compile Include="Areas\Config\Models\AuthorizationRole\CreateModel.cs" />
<Compile Include="Areas\Config\Models\AuthorizationRole\IndexModel.cs" />
<Compile Include="Areas\Config\Models\AuthorizationRole\ShowModel.cs" />
<Compile Include="Areas\Config\Models\AuthorizationRole\SubjectDescriptorModel.cs" />
<Compile Include="Areas\Config\Models\Config\IndexModel.cs" />
<Compile Include="Areas\Config\Models\DeviceBatch\CreateModel.cs" />
<Compile Include="Areas\Config\Models\DeviceBatch\TimelineModel.cs" />
@@ -2035,7 +2036,7 @@
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
<UserProperties BuildVersion_StartDate="2011/7/1" BuildVersion_BuildAction="Both" BuildVersion_UseGlobalSettings="False" BuildVersion_DetectChanges="False" BuildVersion_BuildVersioningStyle="None.DeltaBaseYear.MonthAndDayStamp.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" />
<UserProperties BuildVersion_UpdateFileVersion="True" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.DeltaBaseYear.MonthAndDayStamp.TimeStamp" BuildVersion_DetectChanges="False" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildAction="Both" BuildVersion_StartDate="2011/7/1" />
</VisualStudio>
</ProjectExtensions>
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+28
View File
@@ -2296,6 +2296,12 @@ namespace Disco.Web.Areas.API.Controllers
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult UpdateAdministratorSubjects()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UpdateAdministratorSubjects);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult SearchSubjects()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.SearchSubjects);
@@ -2327,6 +2333,7 @@ namespace Disco.Web.Areas.API.Controllers
public readonly string UpdateClaims = "UpdateClaims";
public readonly string UpdateSubjects = "UpdateSubjects";
public readonly string Delete = "Delete";
public readonly string UpdateAdministratorSubjects = "UpdateAdministratorSubjects";
public readonly string SearchSubjects = "SearchSubjects";
public readonly string Subject = "Subject";
}
@@ -2339,6 +2346,7 @@ namespace Disco.Web.Areas.API.Controllers
public const string UpdateClaims = "UpdateClaims";
public const string UpdateSubjects = "UpdateSubjects";
public const string Delete = "Delete";
public const string UpdateAdministratorSubjects = "UpdateAdministratorSubjects";
public const string SearchSubjects = "SearchSubjects";
public const string Subject = "Subject";
}
@@ -2394,6 +2402,15 @@ namespace Disco.Web.Areas.API.Controllers
public readonly string id = "id";
public readonly string redirect = "redirect";
}
static readonly ActionParamsClass_UpdateAdministratorSubjects s_params_UpdateAdministratorSubjects = new ActionParamsClass_UpdateAdministratorSubjects();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_UpdateAdministratorSubjects UpdateAdministratorSubjectsParams { get { return s_params_UpdateAdministratorSubjects; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_UpdateAdministratorSubjects
{
public readonly string Subjects = "Subjects";
public readonly string redirect = "redirect";
}
static readonly ActionParamsClass_SearchSubjects s_params_SearchSubjects = new ActionParamsClass_SearchSubjects();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_SearchSubjects SearchSubjectsParams { get { return s_params_SearchSubjects; } }
@@ -2489,6 +2506,17 @@ namespace Disco.Web.Areas.API.Controllers
return callInfo;
}
partial void UpdateAdministratorSubjectsOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string[] Subjects, bool redirect);
public override System.Web.Mvc.ActionResult UpdateAdministratorSubjects(string[] Subjects, bool redirect)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UpdateAdministratorSubjects);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Subjects", Subjects);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "redirect", redirect);
UpdateAdministratorSubjectsOverride(callInfo, Subjects, redirect);
return callInfo;
}
partial void SearchSubjectsOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string term);
public override System.Web.Mvc.ActionResult SearchSubjects(string term)