feature: flag permissions

feature: flag permissions
This commit is contained in:
Gary Sharp
2025-07-20 10:45:55 +10:00
parent 7deead494b
commit be7ee4cae8
72 changed files with 5590 additions and 2109 deletions
+7
View File
@@ -197,6 +197,10 @@
<Compile Include="Migrations\202507110430252_DBv27.Designer.cs">
<DependentUpon>202507110430252_DBv27.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\202507170522576_DBv28.cs" />
<Compile Include="Migrations\202507170522576_DBv28.Designer.cs">
<DependentUpon>202507170522576_DBv28.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\Configuration.cs" />
<Compile Include="Migrations\DiscoDataMigrator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -293,6 +297,9 @@
<EmbeddedResource Include="Migrations\202507110430252_DBv27.resx">
<DependentUpon>202507110430252_DBv27.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Migrations\202507170522576_DBv28.resx">
<DependentUpon>202507170522576_DBv28.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
+27
View File
@@ -0,0 +1,27 @@
// <auto-generated />
namespace Disco.Data.Migrations
{
using System.Data.Entity.Migrations;
using System.Data.Entity.Migrations.Infrastructure;
using System.Resources;
public sealed partial class DBv28 : IMigrationMetadata
{
private readonly ResourceManager Resources = new ResourceManager(typeof(DBv28));
string IMigrationMetadata.Id
{
get { return "202507170522576_DBv28"; }
}
string IMigrationMetadata.Source
{
get { return null; }
}
string IMigrationMetadata.Target
{
get { return Resources.GetString("Target"); }
}
}
}
@@ -0,0 +1,40 @@
namespace Disco.Data.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class DBv28 : DbMigration
{
public override void Up()
{
AddColumn("dbo.UserFlagAssignments", "RemoveDate", c => c.DateTime());
AddColumn("dbo.UserFlagAssignments", "RemoveUserId", c => c.String(maxLength: 50));
AddColumn("dbo.UserFlags", "Permissions", c => c.String());
AddColumn("dbo.UserFlags", "DefaultRemoveDays", c => c.Int());
AddColumn("dbo.DeviceFlagAssignments", "RemoveDate", c => c.DateTime());
AddColumn("dbo.DeviceFlagAssignments", "RemoveUserId", c => c.String(maxLength: 50));
AddColumn("dbo.DeviceFlags", "Permissions", c => c.String());
AddColumn("dbo.DeviceFlags", "DefaultRemoveDays", c => c.Int());
AddForeignKey("dbo.UserFlagAssignments", "RemoveUserId", "dbo.Users", "Id");
AddForeignKey("dbo.DeviceFlagAssignments", "RemoveUserId", "dbo.Users", "Id");
CreateIndex("dbo.UserFlagAssignments", "RemoveUserId");
CreateIndex("dbo.DeviceFlagAssignments", "RemoveUserId");
}
public override void Down()
{
DropIndex("dbo.DeviceFlagAssignments", new[] { "RemoveUserId" });
DropIndex("dbo.UserFlagAssignments", new[] { "RemoveUserId" });
DropForeignKey("dbo.DeviceFlagAssignments", "RemoveUserId", "dbo.Users");
DropForeignKey("dbo.UserFlagAssignments", "RemoveUserId", "dbo.Users");
DropColumn("dbo.DeviceFlags", "DefaultRemoveDays");
DropColumn("dbo.DeviceFlags", "Permissions");
DropColumn("dbo.DeviceFlagAssignments", "RemoveUserId");
DropColumn("dbo.DeviceFlagAssignments", "RemoveDate");
DropColumn("dbo.UserFlags", "DefaultRemoveDays");
DropColumn("dbo.UserFlags", "Permissions");
DropColumn("dbo.UserFlagAssignments", "RemoveUserId");
DropColumn("dbo.UserFlagAssignments", "RemoveDate");
}
}
}
File diff suppressed because one or more lines are too long
+2
View File
@@ -59,7 +59,9 @@
<Compile Include="Repository\Device\Flag\DeviceFlag.cs" />
<Compile Include="Repository\Device\Flag\DeviceFlagAssignment.cs" />
<Compile Include="Repository\Device\DeviceComment.cs" />
<Compile Include="Repository\FlagType.cs" />
<Compile Include="Repository\User\UserComment.cs" />
<Compile Include="Repository\FlagPermission.cs" />
<Compile Include="Services\Devices\DeviceFlags\DeviceFlagExportOptions.cs" />
<Compile Include="Services\Devices\DeviceFlags\DeviceFlagExportRecord.cs" />
<Compile Include="Services\Documents\DocumentExportOptions.cs" />
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using Disco.Models.Services.Authorization;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Disco.Models.Repository
{
@@ -27,11 +29,20 @@ namespace Disco.Models.Repository
[DataType(DataType.MultilineText)]
public string OnUnassignmentExpression { get; set; }
[Column("Permissions")]
public string PermissionsJson { get; set; }
[NotMapped]
public FlagPermission Permissions
{
get => FlagPermission.FromFlag(this);
set => PermissionsJson = value?.ToJson();
}
public int? DefaultRemoveDays { get; set; }
public virtual IList<DeviceFlagAssignment> DeviceFlagAssignments { get; set; }
public override string ToString()
{
return Name;
}
=> Name;
}
}
@@ -19,26 +19,28 @@ namespace Disco.Models.Repository
public string AddedUserId { get; set; }
public DateTime? RemovedDate { get; set; }
public string RemovedUserId { get; set; }
public DateTime? RemoveDate { get; set; }
public string RemoveUserId { get; set; }
public string Comments { get; set; }
public string OnAssignmentExpressionResult { get; set; }
public string OnUnassignmentExpressionResult { get; set; }
[ForeignKey(nameof(DeviceFlagId)), InverseProperty("DeviceFlagAssignments")]
[ForeignKey(nameof(DeviceFlagId)), InverseProperty(nameof(Repository.DeviceFlag.DeviceFlagAssignments))]
public virtual DeviceFlag DeviceFlag { get; set; }
[ForeignKey(nameof(DeviceSerialNumber)), InverseProperty("DeviceFlagAssignments")]
[ForeignKey(nameof(DeviceSerialNumber)), InverseProperty(nameof(Repository.Device.DeviceFlagAssignments))]
public virtual Device Device { get; set; }
[ForeignKey("AddedUserId")]
[ForeignKey(nameof(AddedUserId))]
public virtual User AddedUser { get; set; }
[ForeignKey("RemovedUserId")]
[ForeignKey(nameof(RemovedUserId))]
public virtual User RemovedUser { get; set; }
[ForeignKey(nameof(RemoveUserId))]
public virtual User RemoveUser { get; set; }
public override string ToString()
{
return $"Device Flag Id: {DeviceFlagId}; Device Serial Number: {DeviceSerialNumber}; Added: {AddedDate:s}";
}
=> $"Device Flag Id: {DeviceFlagId}; Device Serial Number: {DeviceSerialNumber}; Added: {AddedDate:s}";
}
}
+121
View File
@@ -0,0 +1,121 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace Disco.Models.Repository
{
public class FlagPermission
{
private static readonly FlagPermission DefaultDeviceFlagPermissions = new FlagPermission(FlagType.Device, 0);
private static readonly FlagPermission DefaultUserFlagPermissions = new FlagPermission(FlagType.User, 0);
[JsonIgnore]
public FlagType FlagType { get; }
[JsonIgnore]
public int FlagId { get; }
public bool Inherit { get; set; }
public HashSet<string> CanShowSubjectIds { get; }
public HashSet<string> CanAssignSubjectIds { get; }
public HashSet<string> CanEditSubjectIds { get; }
public HashSet<string> CanRemoveSubjectIds { get; }
private FlagPermission(FlagType flagType, int flagId)
{
FlagType = flagType;
FlagId = flagId;
Inherit = true;
CanShowSubjectIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
CanAssignSubjectIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
CanEditSubjectIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
CanRemoveSubjectIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
}
public bool IsDefault()
{
return ReferenceEquals(this, DefaultDeviceFlagPermissions) ||
ReferenceEquals(this, DefaultUserFlagPermissions);
}
public bool IsSimple()
{
return CanShowSubjectIds.SetEquals(CanAssignSubjectIds) &&
CanAssignSubjectIds.SetEquals(CanEditSubjectIds) &&
CanEditSubjectIds.SetEquals(CanRemoveSubjectIds);
}
public bool HasSubjects()
{
return CanShowSubjectIds.Count > 0 ||
CanAssignSubjectIds.Count > 0 ||
CanEditSubjectIds.Count > 0 ||
CanRemoveSubjectIds.Count > 0;
}
public HashSet<string> AllSubjects()
{
var allSubjects = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
allSubjects.UnionWith(CanShowSubjectIds);
allSubjects.UnionWith(CanAssignSubjectIds);
allSubjects.UnionWith(CanEditSubjectIds);
allSubjects.UnionWith(CanRemoveSubjectIds);
return allSubjects;
}
public static FlagPermission FromFlag(UserFlag userFlag)
{
if (userFlag.PermissionsJson == null)
return DefaultUserFlagPermissions;
var permission = new FlagPermission(FlagType.User, userFlag.Id);
JsonConvert.PopulateObject(userFlag.PermissionsJson, permission);
return permission;
}
public static FlagPermission FromFlag(DeviceFlag deviceFlag)
{
if (deviceFlag.PermissionsJson == null)
return DefaultDeviceFlagPermissions;
var permission = new FlagPermission(FlagType.Device, deviceFlag.Id);
JsonConvert.PopulateObject(deviceFlag.PermissionsJson, permission);
return permission;
}
public static FlagPermission Create(UserFlag userFlag, bool inherit, IEnumerable<string> canShow, IEnumerable<string> canAssign, IEnumerable<string> canEdit, IEnumerable<string> canRemove)
{
var permission = new FlagPermission(FlagType.User, userFlag.Id);
return Create(permission, inherit, canShow, canAssign, canEdit, canRemove);
}
public static FlagPermission Create(DeviceFlag deviceFlag, bool inherit, IEnumerable<string> canShow, IEnumerable<string> canAssign, IEnumerable<string> canEdit, IEnumerable<string> canRemove)
{
var permission = new FlagPermission(FlagType.Device, deviceFlag.Id);
return Create(permission, inherit, canShow, canAssign, canEdit, canRemove);
}
private static FlagPermission Create(FlagPermission permission, bool inherit, IEnumerable<string> canShow, IEnumerable<string> canAssign, IEnumerable<string> canEdit, IEnumerable<string> canRemove)
{
permission.Inherit = inherit;
if (canShow != null)
permission.CanShowSubjectIds.UnionWith(canShow);
if (canAssign != null)
permission.CanAssignSubjectIds.UnionWith(canAssign);
if (canEdit != null)
permission.CanEditSubjectIds.UnionWith(canEdit);
if (canRemove != null)
permission.CanRemoveSubjectIds.UnionWith(canRemove);
return permission;
}
public string ToJson()
{
if (IsDefault())
return null;
return JsonConvert.SerializeObject(this);
}
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace Disco.Models.Repository
{
public enum FlagType
{
User = 1,
Device = 2,
}
}
+15 -4
View File
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using Disco.Models.Services.Authorization;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Disco.Models.Repository
{
@@ -27,11 +29,20 @@ namespace Disco.Models.Repository
[DataType(DataType.MultilineText)]
public string OnUnassignmentExpression { get; set; }
[Column("Permissions")]
public string PermissionsJson { get; set; }
[NotMapped]
public FlagPermission Permissions
{
get => FlagPermission.FromFlag(this);
set => PermissionsJson = value?.ToJson();
}
public int? DefaultRemoveDays { get; set; }
public virtual IList<UserFlagAssignment> UserFlagAssignments { get; set; }
public override string ToString()
{
return Name;
}
=> Name;
}
}
@@ -19,26 +19,28 @@ namespace Disco.Models.Repository
public string AddedUserId { get; set; }
public DateTime? RemovedDate { get; set; }
public string RemovedUserId { get; set; }
public DateTime? RemoveDate { get; set; }
public string RemoveUserId { get; set; }
public string Comments { get; set; }
public string OnAssignmentExpressionResult { get; set; }
public string OnUnassignmentExpressionResult { get; set; }
[ForeignKey("UserFlagId"), InverseProperty("UserFlagAssignments")]
[ForeignKey(nameof(UserFlagId)), InverseProperty(nameof(Repository.UserFlag.UserFlagAssignments))]
public virtual UserFlag UserFlag { get; set; }
[ForeignKey("UserId"), InverseProperty("UserFlagAssignments")]
[ForeignKey(nameof(UserId)), InverseProperty(nameof(Repository.User.UserFlagAssignments))]
public virtual User User { get; set; }
[ForeignKey("AddedUserId")]
[ForeignKey(nameof(AddedUserId))]
public virtual User AddedUser { get; set; }
[ForeignKey("RemovedUserId")]
[ForeignKey(nameof(RemovedUserId))]
public virtual User RemovedUser { get; set; }
[ForeignKey(nameof(RemoveUserId))]
public virtual User RemoveUser { get; set; }
public override string ToString()
{
return $"User Flag Id: {UserFlagId}; User Id: {UserId}; Added: {AddedDate:s}";
}
=> $"User Flag Id: {UserFlagId}; User Id: {UserId}; Added: {AddedDate:s}";
}
}
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Disco.Models.Repository;
using System.Collections.Generic;
namespace Disco.Models.UI.Config.DeviceFlag
{
@@ -11,5 +12,7 @@ namespace Disco.Models.UI.Config.DeviceFlag
IEnumerable<KeyValuePair<string, string>> Icons { get; set; }
IEnumerable<KeyValuePair<string, string>> ThemeColours { get; set; }
FlagPermission Permission { get; set; }
}
}
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Disco.Models.Repository;
using System.Collections.Generic;
namespace Disco.Models.UI.Config.UserFlag
{
@@ -11,5 +12,7 @@ namespace Disco.Models.UI.Config.UserFlag
IEnumerable<KeyValuePair<string, string>> Icons { get; set; }
IEnumerable<KeyValuePair<string, string>> ThemeColours { get; set; }
FlagPermission Permission { get; set; }
}
}
+24 -16
View File
@@ -18,7 +18,7 @@ namespace Disco.Services.Authorization
static Claims()
{
#region Role Claim Dictionary
#region Role Claim Dictionary
_roleClaims = new Dictionary<string, Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>>()
{
{ "Config.DeviceCertificate.DownloadCertificates", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Config.DeviceCertificate.DownloadCertificates, (c, v) => c.Config.DeviceCertificate.DownloadCertificates = v, "Download Certificates", "Can download certificates", false) },
@@ -242,9 +242,9 @@ namespace Disco.Services.Authorization
{ "ComputerAccount", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.ComputerAccount, (c, v) => c.ComputerAccount = v, "Computer Account", "Represents a computer account", true) },
{ "DiscoAdminAccount", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.DiscoAdminAccount, (c, v) => c.DiscoAdminAccount = v, "Disco Administrator Account", "Represents a Disco ICT Administrator account", true) }
};
#endregion
#endregion
#region Role Claim Navigator
#region Role Claim Navigator
_claimNavigator =
new ClaimNavigatorItem("Claims", "Permissions", "Top-level node for all permissions", false, new List<IClaimNavigatorItem>() {
new ClaimNavigatorItem("Config", "Configuration", "Permissions related to Disco ICT Configuration", false, new List<IClaimNavigatorItem>() {
@@ -524,7 +524,7 @@ namespace Disco.Services.Authorization
new ClaimNavigatorItem("ComputerAccount", true),
new ClaimNavigatorItem("DiscoAdminAccount", true)
});
#endregion
#endregion
}
public static ClaimNavigatorItem RoleClaimNavigator
@@ -532,31 +532,36 @@ namespace Disco.Services.Authorization
get { return _claimNavigator; }
}
internal static Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool> GetClaimDefinition(string ClaimKey) {
internal static Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool> GetClaimDefinition(string ClaimKey)
{
if (_roleClaims.TryGetValue(ClaimKey, out var claimDef))
return claimDef;
throw new ArgumentException("Unknown Claim Key", nameof(ClaimKey));
}
public static Func<RoleClaims, bool> GetClaimAccessor(string ClaimKey) {
public static Func<RoleClaims, bool> GetClaimAccessor(string ClaimKey)
{
if (_roleClaims.TryGetValue(ClaimKey, out var claimDef))
return claimDef.Item1;
throw new ArgumentException("Unknown Claim Key", nameof(ClaimKey));
}
public static Action<RoleClaims, bool> GetClaimSetter(string ClaimKey) {
public static Action<RoleClaims, bool> GetClaimSetter(string ClaimKey)
{
if (_roleClaims.TryGetValue(ClaimKey, out var claimDef))
return claimDef.Item2;
throw new ArgumentException("Unknown Claim Key", nameof(ClaimKey));
}
public static Tuple<string, string, bool> GetClaimDetails(string ClaimKey) {
public static Tuple<string, string, bool> GetClaimDetails(string ClaimKey)
{
if (_roleClaims.TryGetValue(ClaimKey, out var claimDef))
return Tuple.Create(claimDef.Item3, claimDef.Item4, claimDef.Item5);
throw new ArgumentException("Unknown Claim Key", "ClaimKey");
}
public static RoleClaims BuildClaims(IEnumerable<string> ClaimKeys){
public static RoleClaims BuildClaims(IEnumerable<string> ClaimKeys)
{
var c = new RoleClaims();
foreach (var claimKey in ClaimKeys)
c.Set(claimKey, true);
@@ -570,9 +575,10 @@ namespace Disco.Services.Authorization
return _roleClaims.Where(rc => rc.Value.Item1(claims)).Select(rc => rc.Key).ToList();
}
public static RoleClaims AdministratorClaims() {
public static RoleClaims AdministratorClaims()
{
var c = new RoleClaims();
#region Set All Administrator Claims
#region Set All Administrator Claims
c.Config.DeviceCertificate.DownloadCertificates = true;
c.Config.Enrolment.Configure = true;
c.Config.Enrolment.DownloadBootstrapper = true;
@@ -792,17 +798,19 @@ namespace Disco.Services.Authorization
c.User.ShowFlagAssignments = true;
c.User.ShowJobs = true;
c.DiscoAdminAccount = true;
#endregion
#endregion
return c;
}
public static RoleClaims ComputerAccountClaims() {
return new RoleClaims() {
public static RoleClaims ComputerAccountClaims()
{
return new RoleClaims()
{
ComputerAccount = true
};
}
#region Role Claim Constants
#region Role Claim Constants
/// <summary>Configuration
/// <para>Permissions related to Disco ICT Configuration</para>
@@ -2099,7 +2107,7 @@ namespace Disco.Services.Authorization
/// <para>Represents a Disco ICT Administrator account</para>
/// </summary>
public const string DiscoAdminAccount = "DiscoAdminAccount";
#endregion
#endregion
}
public static class ClaimExtensions
{
+24 -16
View File
@@ -66,17 +66,17 @@ namespace Disco.Services.Authorization
static Claims()
{
#region Role Claim Dictionary
#region Role Claim Dictionary
_roleClaims = new Dictionary<string, Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>>()
{
<#WriteAccessHashes(permissionRoot);#>
};
#endregion
#endregion
#region Role Claim Navigator
#region Role Claim Navigator
_claimNavigator =
<#WriteNavigator(permissionRoot);#>;
#endregion
#endregion
}
public static ClaimNavigatorItem RoleClaimNavigator
@@ -84,31 +84,36 @@ namespace Disco.Services.Authorization
get { return _claimNavigator; }
}
internal static Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool> GetClaimDefinition(string ClaimKey) {
internal static Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool> GetClaimDefinition(string ClaimKey)
{
if (_roleClaims.TryGetValue(ClaimKey, out var claimDef))
return claimDef;
throw new ArgumentException("Unknown Claim Key", nameof(ClaimKey));
}
public static Func<RoleClaims, bool> GetClaimAccessor(string ClaimKey) {
public static Func<RoleClaims, bool> GetClaimAccessor(string ClaimKey)
{
if (_roleClaims.TryGetValue(ClaimKey, out var claimDef))
return claimDef.Item1;
throw new ArgumentException("Unknown Claim Key", nameof(ClaimKey));
}
public static Action<RoleClaims, bool> GetClaimSetter(string ClaimKey) {
public static Action<RoleClaims, bool> GetClaimSetter(string ClaimKey)
{
if (_roleClaims.TryGetValue(ClaimKey, out var claimDef))
return claimDef.Item2;
throw new ArgumentException("Unknown Claim Key", nameof(ClaimKey));
}
public static Tuple<string, string, bool> GetClaimDetails(string ClaimKey) {
public static Tuple<string, string, bool> GetClaimDetails(string ClaimKey)
{
if (_roleClaims.TryGetValue(ClaimKey, out var claimDef))
return Tuple.Create(claimDef.Item3, claimDef.Item4, claimDef.Item5);
throw new ArgumentException("Unknown Claim Key", "ClaimKey");
}
public static RoleClaims BuildClaims(IEnumerable<string> ClaimKeys){
public static RoleClaims BuildClaims(IEnumerable<string> ClaimKeys)
{
var c = new RoleClaims();
foreach (var claimKey in ClaimKeys)
c.Set(claimKey, true);
@@ -122,23 +127,26 @@ namespace Disco.Services.Authorization
return _roleClaims.Where(rc => rc.Value.Item1(claims)).Select(rc => rc.Key).ToList();
}
public static RoleClaims AdministratorClaims() {
public static RoleClaims AdministratorClaims()
{
var c = new RoleClaims();
#region Set All Administrator Claims
#region Set All Administrator Claims
<#WriteAdministratorClaims(permissionRoot);#>
#endregion
#endregion
return c;
}
public static RoleClaims ComputerAccountClaims() {
return new RoleClaims() {
public static RoleClaims ComputerAccountClaims()
{
return new RoleClaims()
{
ComputerAccount = true
};
}
#region Role Claim Constants
#region Role Claim Constants
<#WritePermissionConsts(permissionRoot);#>
#endregion
#endregion
}
public static class ClaimExtensions
{
+44 -58
View File
@@ -4,6 +4,7 @@ using Disco.Models.Services.Authorization;
using Disco.Services.Interop.ActiveDirectory;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
@@ -16,41 +17,41 @@ namespace Disco.Services.Authorization.Roles
internal const string ClaimsJsonEmpty = "null";
internal static readonly string[] _RequiredAdministratorSubjectIds = new string[] { "Domain Admins" };
private static List<RoleToken> _Cache;
private static ConcurrentDictionary<int, RoleToken> cache;
private static RoleToken _AdministratorToken;
internal static void Initialize(DiscoDataContext Database)
internal static void Initialize(DiscoDataContext database)
{
MigrateAuthorizationRoles(Database);
MigrateAuthorizationRoles(database);
_Cache = Database.AuthorizationRoles.ToList().Select(ar => RoleToken.FromAuthorizationRole(ar)).ToList();
cache = new ConcurrentDictionary<int, RoleToken>(database.AuthorizationRoles.ToList().Select(ar => RoleToken.FromAuthorizationRole(ar)).ToDictionary(r => r.Role.Id));
// Add System Roles
AddSystemRoles(Database);
AddSystemRoles(database);
}
private static void AddSystemRoles(DiscoDataContext Database)
private static void AddSystemRoles(DiscoDataContext database)
{
// Disco Administrators
_AdministratorToken = RoleToken.FromAuthorizationRole(new AuthorizationRole()
{
Id = AdministratorsTokenId,
Name = "Disco Administrators",
SubjectIds = string.Join(",", GenerateAdministratorSubjectIds(Database))
SubjectIds = string.Join(",", GenerateAdministratorSubjectIds(database))
}, Claims.AdministratorClaims());
_Cache.Add(_AdministratorToken);
cache.TryAdd(AdministratorsTokenId, _AdministratorToken);
// Computer Accounts
_Cache.Add(RoleToken.FromAuthorizationRole(new AuthorizationRole()
cache.TryAdd(ComputerAccountTokenId, RoleToken.FromAuthorizationRole(new AuthorizationRole()
{
Id = ComputerAccountTokenId,
Name = "Domain Computer Account"
}, Claims.ComputerAccountClaims()));
}
private static IEnumerable<string> GenerateAdministratorSubjectIds(DiscoDataContext Database)
private static IEnumerable<string> GenerateAdministratorSubjectIds(DiscoDataContext database)
{
var configuredSubjectIds = Database.DiscoConfiguration.Administrators.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => ActiveDirectory.ParseDomainAccountId(s));
var configuredSubjectIds = database.DiscoConfiguration.Administrators.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => ActiveDirectory.ParseDomainAccountId(s));
return RequiredAdministratorSubjectIds
.Concat(configuredSubjectIds)
@@ -58,94 +59,79 @@ namespace Disco.Services.Authorization.Roles
.OrderBy(s => s);
}
public static IEnumerable<string> RequiredAdministratorSubjectIds
{
get
{
return _RequiredAdministratorSubjectIds.Select(s => ActiveDirectory.ParseDomainAccountId(s));
}
}
=> _RequiredAdministratorSubjectIds.Select(s => ActiveDirectory.ParseDomainAccountId(s));
public static IEnumerable<string> AdministratorSubjectIds
{
get
{
return _AdministratorToken.SubjectIds.ToList();
}
}
=> _AdministratorToken.SubjectIds.ToList();
public static void UpdateAdministratorSubjectIds(DiscoDataContext Database, IEnumerable<string> SubjectIds)
public static void UpdateAdministratorSubjectIds(DiscoDataContext database, IEnumerable<string> subjectIds)
{
// Clean
SubjectIds = SubjectIds
subjectIds = subjectIds
.Where(s => !string.IsNullOrWhiteSpace(s))
.Concat(RequiredAdministratorSubjectIds)
.Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(s => s);
var subjectIdsString = string.Join(",", SubjectIds);
var subjectIdsString = string.Join(",", subjectIds);
// Update Database
Database.DiscoConfiguration.Administrators = subjectIdsString;
Database.SaveChanges();
database.DiscoConfiguration.Administrators = subjectIdsString;
database.SaveChanges();
// Update State
_AdministratorToken.SubjectIds = SubjectIds.ToList();
_AdministratorToken.SubjectIdHashes = new HashSet<string>(SubjectIds, StringComparer.OrdinalIgnoreCase);
_AdministratorToken.SubjectIds = subjectIds.ToList();
_AdministratorToken.SubjectIdHashes = new HashSet<string>(subjectIds, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Create a clone of an Authorization Role
/// <para>Creates immutable clones to avoid side-effects</para>
/// </summary>
/// <param name="TemplateRole">Authorization Role to Clone</param>
/// <param name="templateRole">Authorization Role to Clone</param>
/// <returns>A copy of the Authorization Role</returns>
private static AuthorizationRole CloneAuthoriationRole(AuthorizationRole TemplateRole)
private static AuthorizationRole CloneAuthoriationRole(AuthorizationRole templateRole)
{
return new AuthorizationRole()
{
Id = TemplateRole.Id,
Name = TemplateRole.Name,
ClaimsJson = TemplateRole.ClaimsJson,
SubjectIds = TemplateRole.SubjectIds
Id = templateRole.Id,
Name = templateRole.Name,
ClaimsJson = templateRole.ClaimsJson,
SubjectIds = templateRole.SubjectIds
};
}
internal static RoleToken AddRole(AuthorizationRole Role)
{
var token = RoleToken.FromAuthorizationRole(CloneAuthoriationRole(Role));
_Cache.Add(token);
return token;
}
internal static void RemoveRole(AuthorizationRole Role)
{
var token = GetRoleToken(Role.Id);
if (token != null)
_Cache.Remove(token);
cache.TryRemove(Role.Id, out _);
}
internal static RoleToken UpdateRole(AuthorizationRole Role)
internal static RoleToken AddOrUpdateRole(AuthorizationRole role)
{
RemoveRole(Role);
return AddRole(Role);
var token = RoleToken.FromAuthorizationRole(CloneAuthoriationRole(role));
cache.AddOrUpdate(token.Role.Id, token, (i, e) => token);
return token;
}
internal static RoleToken GetRoleToken(int Id)
internal static RoleToken GetRoleToken(int id)
{
return _Cache.FirstOrDefault(t => t.Role.Id == Id);
if (cache.TryGetValue(id, out var result))
return result;
else
return null;
}
internal static RoleToken GetRoleToken(string SecurityGroup)
internal static RoleToken GetRoleToken(string securityGroup)
{
return _Cache.FirstOrDefault(t => t.SubjectIdHashes.Contains(SecurityGroup));
return cache.Values.FirstOrDefault(t => t.SubjectIdHashes.Contains(securityGroup));
}
internal static List<IRoleToken> GetRoleTokens(IEnumerable<string> SecurityGroup)
internal static List<IRoleToken> GetRoleTokens(IEnumerable<string> securityGroups)
{
return _Cache.Where(t => SecurityGroup.Any(sg => t.SubjectIdHashes.Contains(sg))).Cast<IRoleToken>().ToList();
return cache.Values.Where(t => securityGroups.Any(sg => t.SubjectIdHashes.Contains(sg))).Cast<IRoleToken>().ToList();
}
internal static List<IRoleToken> GetRoleTokens(IEnumerable<string> SecurityGroup, User User)
internal static List<IRoleToken> GetRoleTokens(IEnumerable<string> securityGroups, User user)
{
var subjectIds = SecurityGroup.Concat(new string[] { User.UserId });
var subjectIds = securityGroups.Concat(new string[] { user.UserId });
return _Cache.Where(t => subjectIds.Any(sg => t.SubjectIdHashes.Contains(sg))).Cast<IRoleToken>().ToList();
return cache.Values.Where(t => subjectIds.Any(sg => t.SubjectIdHashes.Contains(sg))).Cast<IRoleToken>().ToList();
}
/// <summary>
+11 -17
View File
@@ -8,7 +8,7 @@ namespace Disco.Services.Devices.DeviceFlags
{
internal class Cache
{
private ConcurrentDictionary<int, DeviceFlag> _Cache;
private ConcurrentDictionary<int, (DeviceFlag, FlagPermission permission)> cache;
public Cache(DiscoDataContext Database)
{
@@ -26,36 +26,30 @@ namespace Disco.Services.Devices.DeviceFlags
var flags = Database.DeviceFlags.ToList();
// Add Queues to In-Memory Cache
_Cache = new ConcurrentDictionary<int, DeviceFlag>(flags.Select(f => new KeyValuePair<int, DeviceFlag>(f.Id, f)));
cache = new ConcurrentDictionary<int, (DeviceFlag, FlagPermission permission)>(flags.Select(f => new KeyValuePair<int, (DeviceFlag, FlagPermission permission)>(f.Id, (f, f.Permissions))));
}
public DeviceFlag GetDeviceFlag(int deviceFlagId)
public (DeviceFlag flag, FlagPermission permission) GetDeviceFlag(int deviceFlagId)
{
if (_Cache.TryGetValue(deviceFlagId, out var item))
if (cache.TryGetValue(deviceFlagId, out var item))
return item;
else
return null;
return (null, null);
}
public List<DeviceFlag> GetDeviceFlags()
public List<(DeviceFlag flag, FlagPermission permission)> GetDeviceFlags()
{
return _Cache.Values.ToList();
return cache.Values.ToList();
}
public void AddOrUpdate(DeviceFlag flag)
{
_Cache.AddOrUpdate(flag.Id, flag, (key, existingItem) => flag);
var value = (flag, flag.Permissions);
cache.AddOrUpdate(flag.Id, value, (key, existingItem) => value);
}
public DeviceFlag Remove(int deviceFlagId)
public void Remove(int deviceFlagId)
{
if (_Cache.TryRemove(deviceFlagId, out var item))
return item;
else
return null;
}
public DeviceFlag Remove(DeviceFlag deviceFlag)
{
return Remove(deviceFlag.Id);
cache.TryRemove(deviceFlagId, out _);
}
}
}
@@ -1,6 +1,7 @@
using Disco.Data.Repository;
using Disco.Models.Repository;
using Disco.Services.Authorization;
using Disco.Services.Devices.DeviceFlags;
using Disco.Services.Expressions;
using Disco.Services.Logging;
using Disco.Services.Users;
@@ -15,16 +16,18 @@ namespace Disco.Services
{
#region Edit Comments
public static bool CanEditComments(this DeviceFlagAssignment fa)
public static bool CanEdit(this DeviceFlagAssignment fa)
{
return UserService.CurrentAuthorization.Has(Claims.Device.Actions.EditFlags);
var (_, permission) = DeviceFlagService.GetDeviceFlag(fa.DeviceFlagId);
return permission.CanEdit();
}
public static void OnEditComments(this DeviceFlagAssignment fa, string Comments)
public static void OnEdit(this DeviceFlagAssignment fa, string comments)
{
if (!fa.CanEditComments())
if (!fa.CanEdit())
throw new InvalidOperationException("Editing comments for device flags is denied");
fa.Comments = string.IsNullOrWhiteSpace(Comments) ? null : Comments.Trim();
fa.Comments = string.IsNullOrWhiteSpace(comments) ? null : comments.Trim();
}
#endregion
@@ -34,36 +37,38 @@ namespace Disco.Services
if (fa.RemovedDate.HasValue)
return false;
return UserService.CurrentAuthorization.Has(Claims.Device.Actions.RemoveFlags);
var (_, permission) = DeviceFlagService.GetDeviceFlag(fa.DeviceFlagId);
return permission.CanRemove();
}
public static void OnRemove(this DeviceFlagAssignment fa, DiscoDataContext Database, User RemovingUser)
public static void OnRemove(this DeviceFlagAssignment fa, DiscoDataContext database)
{
if (!fa.CanRemove())
throw new InvalidOperationException("Removing device flags is denied");
fa.OnRemoveUnsafe(Database, RemovingUser);
fa.OnRemoveUnsafe(database, UserService.CurrentUser);
}
public static void OnRemoveUnsafe(this DeviceFlagAssignment fa, DiscoDataContext Database, User RemovingUser)
public static void OnRemoveUnsafe(this DeviceFlagAssignment fa, DiscoDataContext database, User removingUser)
{
fa = Database.DeviceFlagAssignments
fa = database.DeviceFlagAssignments
.Include(a => a.DeviceFlag)
.First(a => a.Id == fa.Id);
RemovingUser = Database.Users.First(u => u.UserId == RemovingUser.UserId);
removingUser = database.Users.First(u => u.UserId == removingUser.UserId);
fa.RemovedDate = DateTime.Now;
fa.RemovedUserId = RemovingUser.UserId;
fa.RemovedUserId = removingUser.UserId;
if (!string.IsNullOrWhiteSpace(fa.DeviceFlag.OnUnassignmentExpression))
{
try
{
Database.SaveChanges();
var expressionResult = fa.EvaluateOnUnassignmentExpression(Database, RemovingUser, fa.AddedDate);
database.SaveChanges();
var expressionResult = fa.EvaluateOnUnassignmentExpression(database, removingUser, fa.AddedDate);
if (!string.IsNullOrWhiteSpace(expressionResult))
{
fa.OnUnassignmentExpressionResult = expressionResult;
Database.SaveChanges();
database.SaveChanges();
}
}
catch (Exception ex)
@@ -75,58 +80,52 @@ namespace Disco.Services
#endregion
#region Add
public static bool CanAddDeviceFlags(this Device d)
{
return UserService.CurrentAuthorization.Has(Claims.Device.Actions.AddFlags);
}
public static bool CanAddDeviceFlag(this Device d, DeviceFlag flag)
{
// Shortcut
if (!d.CanAddDeviceFlags())
return false;
// Already has Device Flag?
if (d.DeviceFlagAssignments.Any(fa => !fa.RemovedDate.HasValue && fa.DeviceFlagId == flag.Id))
return false;
return true;
var (_, permission) = DeviceFlagService.GetDeviceFlag(flag.Id);
return permission.CanAssign();
}
public static DeviceFlagAssignment OnAddDeviceFlag(this Device d, DiscoDataContext Database, DeviceFlag flag, User AddingUser, string Comments)
public static DeviceFlagAssignment OnAddDeviceFlag(this Device d, DiscoDataContext database, DeviceFlag flag, string comments)
{
if (!d.CanAddDeviceFlag(flag))
throw new InvalidOperationException("Adding device flag is denied");
return d.OnAddDeviceFlagUnsafe(Database, flag, AddingUser, Comments);
return d.OnAddDeviceFlagUnsafe(database, flag, UserService.CurrentUser, comments);
}
public static DeviceFlagAssignment OnAddDeviceFlagUnsafe(this Device d, DiscoDataContext Database, DeviceFlag flag, User AddingUser, string Comments)
public static DeviceFlagAssignment OnAddDeviceFlagUnsafe(this Device d, DiscoDataContext database, DeviceFlag flag, User addingUser, string comments)
{
flag = Database.DeviceFlags.First(f => f.Id == flag.Id);
d = Database.Devices.First(de => de.SerialNumber == d.SerialNumber);
AddingUser = Database.Users.First(user => user.UserId == AddingUser.UserId);
flag = database.DeviceFlags.First(f => f.Id == flag.Id);
d = database.Devices.First(de => de.SerialNumber == d.SerialNumber);
addingUser = database.Users.First(user => user.UserId == addingUser.UserId);
var fa = new DeviceFlagAssignment()
{
DeviceFlag = flag,
Device = d,
AddedDate = DateTime.Now,
AddedUser = AddingUser,
AddedUserId = AddingUser.UserId,
Comments = string.IsNullOrWhiteSpace(Comments) ? null : Comments.Trim()
AddedUser = addingUser,
AddedUserId = addingUser.UserId,
Comments = string.IsNullOrWhiteSpace(comments) ? null : comments.Trim()
};
Database.DeviceFlagAssignments.Add(fa);
database.DeviceFlagAssignments.Add(fa);
if (!string.IsNullOrWhiteSpace(flag.OnAssignmentExpression))
{
try
{
Database.SaveChanges();
var expressionResult = fa.EvaluateOnAssignmentExpression(Database, AddingUser, fa.AddedDate);
database.SaveChanges();
var expressionResult = fa.EvaluateOnAssignmentExpression(database, addingUser, fa.AddedDate);
if (!string.IsNullOrWhiteSpace(expressionResult))
{
fa.OnAssignmentExpressionResult = expressionResult;
Database.SaveChanges();
database.SaveChanges();
}
}
catch (Exception ex)
@@ -13,7 +13,7 @@ namespace Disco.Services.Devices.DeviceFlags
{
public static class DeviceFlagService
{
private static Cache _cache;
private static Cache cache;
internal static Lazy<IObservable<RepositoryMonitorEvent>> DeviceFlagAssignmentRepositoryEvents;
static DeviceFlagService()
@@ -31,18 +31,51 @@ namespace Disco.Services.Devices.DeviceFlags
public static void Initialize(DiscoDataContext database)
{
_cache = new Cache(database);
cache = new Cache(database);
// Initialize Managed Groups (if configured)
_cache.GetDeviceFlags().ForEach(uf =>
cache.GetDeviceFlags().ForEach(uf =>
{
DeviceFlagDevicesManagedGroup.Initialize(uf);
DeviceFlagDeviceAssignedUsersManagedGroup.Initialize(uf);
DeviceFlagDevicesManagedGroup.Initialize(uf.flag);
DeviceFlagDeviceAssignedUsersManagedGroup.Initialize(uf.flag);
});
}
public static List<DeviceFlag> GetDeviceFlags() { return _cache.GetDeviceFlags(); }
public static DeviceFlag GetDeviceFlag(int deviceFlagId) { return _cache.GetDeviceFlag(deviceFlagId); }
public static IEnumerable<(DeviceFlag flag, FlagPermission permission)> GetDeviceFlags() { return cache.GetDeviceFlags(); }
public static (DeviceFlag flag, FlagPermission permission) GetDeviceFlag(int deviceFlagId) { return cache.GetDeviceFlag(deviceFlagId); }
public static DeviceFlag GetAvailableUserFlag(int deviceFlagId, Device targetDevice)
{
var (deviceFlag, permission) = cache.GetDeviceFlag(deviceFlagId);
if (targetDevice.DeviceFlagAssignments
.Where(a => a.DeviceFlagId == deviceFlagId && !a.RemovedDate.HasValue).Any())
return null;
if (permission.CanAssign())
return deviceFlag;
return null;
}
public static IEnumerable<DeviceFlag> GetAvailableDeviceFlags(Device targetDevice)
{
var records = cache.GetDeviceFlags();
var usedFlags = targetDevice.DeviceFlagAssignments
.Where(a => !a.RemovedDate.HasValue)
.Select(a => a.DeviceFlagId)
.ToList();
foreach (var (flag, permission) in records)
{
if (usedFlags.Contains(flag.Id))
continue;
if (permission.CanAssign())
yield return flag;
}
}
#region Device Flag Maintenance
public static DeviceFlag CreateDeviceFlag(DiscoDataContext database, string name, string description)
@@ -52,7 +85,7 @@ namespace Disco.Services.Devices.DeviceFlags
throw new ArgumentException("The Device Flag Name is required", nameof(name));
// Name Unique
if (_cache.GetDeviceFlags().Any(f => f.Name.Equals(name, StringComparison.Ordinal)))
if (cache.GetDeviceFlags().Any(f => f.flag.Name.Equals(name, StringComparison.Ordinal)))
throw new ArgumentException("Another Device Flag already exists with that name", nameof(name));
// Clone to break reference
@@ -67,7 +100,7 @@ namespace Disco.Services.Devices.DeviceFlags
database.DeviceFlags.Add(flag);
database.SaveChanges();
_cache.AddOrUpdate(flag);
cache.AddOrUpdate(flag);
return flag;
}
@@ -78,12 +111,12 @@ namespace Disco.Services.Devices.DeviceFlags
throw new ArgumentException("The Device Flag Name is required", nameof(deviceFlag));
// Name Unique
if (_cache.GetDeviceFlags().Any(f => f.Id != deviceFlag.Id && f.Name == deviceFlag.Name))
if (cache.GetDeviceFlags().Any(f => f.flag.Id != deviceFlag.Id && f.flag.Name == deviceFlag.Name))
throw new ArgumentException("Another Device Flag already exists with that name", nameof(deviceFlag));
database.SaveChanges();
_cache.AddOrUpdate(deviceFlag);
cache.AddOrUpdate(deviceFlag);
DeviceFlagDevicesManagedGroup.Initialize(deviceFlag);
DeviceFlagDeviceAssignedUsersManagedGroup.Initialize(deviceFlag);
@@ -113,7 +146,7 @@ namespace Disco.Services.Devices.DeviceFlags
database.SaveChanges();
// Remove from Cache
_cache.Remove(deviceFlagId);
cache.Remove(deviceFlagId);
status.Finished($"Successfully Deleted Device Flag: '{flag.Name}' [{flag.Id}]");
}
@@ -140,7 +173,7 @@ namespace Disco.Services.Devices.DeviceFlags
{
status.UpdateStatus((chunkIndexOffset + index) * progressInterval, $"Assigning Flag: {device}");
return device.OnAddDeviceFlag(database, deviceFlag, technician, comments);
return device.OnAddDeviceFlagUnsafe(database, deviceFlag, technician, comments);
}).ToList();
// Save Chunk Items to Database
@@ -206,7 +239,7 @@ namespace Disco.Services.Devices.DeviceFlags
{
status.UpdateStatus((chunkIndexOffset + index) * progressInterval, $"Assigning Flag: {device}");
return device.OnAddDeviceFlag(database, deviceFlag, technician, comments);
return device.OnAddDeviceFlagUnsafe(database, deviceFlag, technician, comments);
}).ToList();
// Save Chunk Items to Database
@@ -229,11 +262,11 @@ namespace Disco.Services.Devices.DeviceFlags
public static string RandomUnusedIcon()
{
return UIHelpers.RandomIcon(_cache.GetDeviceFlags().Select(f => f.Icon));
return UIHelpers.RandomIcon(cache.GetDeviceFlags().Select(f => f.flag.Icon));
}
public static string RandomUnusedThemeColour()
{
return UIHelpers.RandomThemeColour(_cache.GetDeviceFlags().Select(f => f.IconColour));
return UIHelpers.RandomThemeColour(cache.GetDeviceFlags().Select(f => f.flag.IconColour));
}
}
}
+1
View File
@@ -609,6 +609,7 @@
<Compile Include="Users\Contact\UserContactService.cs" />
<Compile Include="Users\UserExtensions.cs" />
<Compile Include="Users\UserFlags\Cache.cs" />
<Compile Include="Users\UserFlags\FlagPermissionExtensions.cs" />
<Compile Include="Users\UserFlags\UserFlagExport.cs" />
<Compile Include="Users\UserFlags\UserFlagExtensions.cs" />
<Compile Include="Users\UserFlags\UserFlagUserDevicesManagedGroup.cs" />
+11 -17
View File
@@ -8,7 +8,7 @@ namespace Disco.Services.Users.UserFlags
{
internal class Cache
{
private ConcurrentDictionary<int, UserFlag> _Cache;
private ConcurrentDictionary<int, (UserFlag flag, FlagPermission permission)> cache;
public Cache(DiscoDataContext Database)
{
@@ -26,36 +26,30 @@ namespace Disco.Services.Users.UserFlags
var flags = Database.UserFlags.ToList();
// Add Queues to In-Memory Cache
_Cache = new ConcurrentDictionary<int, UserFlag>(flags.Select(f => new KeyValuePair<int, UserFlag>(f.Id, f)));
cache = new ConcurrentDictionary<int, (UserFlag, FlagPermission)>(flags.Select(f => new KeyValuePair<int, (UserFlag, FlagPermission)>(f.Id, (f, f.Permissions))));
}
public UserFlag GetUserFlag(int UserFlagId)
public (UserFlag flag, FlagPermission permission) GetUserFlag(int UserFlagId)
{
if (_Cache.TryGetValue(UserFlagId, out var item))
if (cache.TryGetValue(UserFlagId, out var item))
return item;
else
return null;
return (null, null);
}
public List<UserFlag> GetUserFlags()
public List<(UserFlag flag, FlagPermission permission)> GetUserFlags()
{
return _Cache.Values.ToList();
return cache.Values.ToList();
}
public void AddOrUpdate(UserFlag UserFlag)
{
_Cache.AddOrUpdate(UserFlag.Id, UserFlag, (key, existingItem) => UserFlag);
var value = (UserFlag, UserFlag.Permissions);
cache.AddOrUpdate(UserFlag.Id, value, (key, existingItem) => value);
}
public UserFlag Remove(int UserFlagId)
public void Remove(int UserFlagId)
{
if (_Cache.TryRemove(UserFlagId, out var item))
return item;
else
return null;
}
public UserFlag Remove(UserFlag UserFlag)
{
return Remove(UserFlag.Id);
cache.TryRemove(UserFlagId, out _);
}
}
}
@@ -0,0 +1,144 @@
using Disco.Models.Repository;
using Disco.Services.Authorization;
using Disco.Services.Devices.DeviceFlags;
using Disco.Services.Users;
using Disco.Services.Users.UserFlags;
using System.Collections.Generic;
using System.Linq;
namespace Disco
{
public static class FlagPermissionExtensions
{
public static bool CanShow(this FlagPermission permission)
{
var authorization = UserService.CurrentAuthorization;
// inherited permission
if (permission.Inherit &&
authorization.Has(permission.FlagType == FlagType.User ? Claims.User.ShowFlagAssignments : Claims.Device.ShowFlagAssignments))
{
return true;
}
// permission override
if (permission != null && (
permission.CanShowSubjectIds.Contains(authorization.User.UserId) ||
permission.CanShowSubjectIds.Overlaps(authorization.GroupMembership) ||
permission.CanShowSubjectIds.Overlaps(authorization.RoleTokens.Select(r => $"[{r.Role.Id}]"))
))
{
return true;
}
return false;
}
public static bool CanAssign(this FlagPermission permission)
{
var authorization = UserService.CurrentAuthorization;
// inherited permission
if (permission.Inherit &&
authorization.Has(permission.FlagType == FlagType.User ? Claims.User.Actions.AddFlags : Claims.Device.Actions.AddFlags))
{
return true;
}
// permission override
if (permission != null && (
permission.CanAssignSubjectIds.Contains(authorization.User.UserId) ||
permission.CanAssignSubjectIds.Overlaps(authorization.GroupMembership) ||
permission.CanAssignSubjectIds.Overlaps(authorization.RoleTokens.Select(r => $"[{r.Role.Id}]"))
))
{
return true;
}
return false;
}
public static bool CanEdit(this FlagPermission permission)
{
var authorization = UserService.CurrentAuthorization;
// inherited permission
if (permission.Inherit &&
authorization.Has(permission.FlagType == FlagType.User ? Claims.User.Actions.EditFlags : Claims.Device.Actions.EditFlags))
{
return true;
}
// permission override
if (permission != null && (
permission.CanEditSubjectIds.Contains(authorization.User.UserId) ||
permission.CanEditSubjectIds.Overlaps(authorization.GroupMembership) ||
permission.CanEditSubjectIds.Overlaps(authorization.RoleTokens.Select(r => $"[{r.Role.Id}]"))
))
{
return true;
}
return false;
}
public static bool CanRemove(this FlagPermission permission)
{
var authorization = UserService.CurrentAuthorization;
// inherited permission
if (permission.Inherit &&
authorization.Has(permission.FlagType == FlagType.User ? Claims.User.Actions.RemoveFlags : Claims.Device.Actions.RemoveFlags))
{
return true;
}
// permission override
if (permission != null && (
permission.CanRemoveSubjectIds.Contains(authorization.User.UserId) ||
permission.CanRemoveSubjectIds.Overlaps(authorization.GroupMembership) ||
permission.CanRemoveSubjectIds.Overlaps(authorization.RoleTokens.Select(r => $"[{r.Role.Id}]"))
))
{
return true;
}
return false;
}
public static bool CanShowAny(this IEnumerable<UserFlagAssignment> assignments)
{
if (assignments == null)
return false;
foreach (var assignment in assignments)
{
if (assignment.RemovedDate.HasValue)
continue;
var (_, permission) = UserFlagService.GetUserFlag(assignment.UserFlagId);
if (permission.CanShow())
return true;
}
return false;
}
public static bool CanShowAny(this IEnumerable<DeviceFlagAssignment> assignments)
{
if (assignments == null)
return false;
foreach (var assignment in assignments)
{
if (assignment.RemovedDate.HasValue)
continue;
var (_, permission) = DeviceFlagService.GetDeviceFlag(assignment.DeviceFlagId);
if (permission.CanShow())
return true;
}
return false;
}
}
}
@@ -4,6 +4,7 @@ using Disco.Services.Authorization;
using Disco.Services.Expressions;
using Disco.Services.Logging;
using Disco.Services.Users;
using Disco.Services.Users.UserFlags;
using System;
using System.Collections;
using System.Linq;
@@ -14,16 +15,18 @@ namespace Disco.Services
{
#region Edit Comments
public static bool CanEditComments(this UserFlagAssignment fa)
public static bool CanEdit(this UserFlagAssignment fa)
{
return UserService.CurrentAuthorization.Has(Claims.User.Actions.EditFlags);
var (_, permission) = UserFlagService.GetUserFlag(fa.UserFlagId);
return permission.CanEdit();
}
public static void OnEditComments(this UserFlagAssignment fa, string Comments)
public static void OnEdit(this UserFlagAssignment fa, string comments)
{
if (!fa.CanEditComments())
if (!fa.CanEdit())
throw new InvalidOperationException("Editing comments for user flags is denied");
fa.Comments = string.IsNullOrWhiteSpace(Comments) ? null : Comments.Trim();
fa.Comments = string.IsNullOrWhiteSpace(comments) ? null : comments.Trim();
}
#endregion
@@ -33,34 +36,36 @@ namespace Disco.Services
if (fa.RemovedDate.HasValue)
return false;
return UserService.CurrentAuthorization.Has(Claims.User.Actions.RemoveFlags);
var (_, permission) = UserFlagService.GetUserFlag(fa.UserFlagId);
return permission.CanRemove();
}
public static void OnRemove(this UserFlagAssignment fa, DiscoDataContext Database, User RemovingUser)
public static void OnRemove(this UserFlagAssignment fa, DiscoDataContext database)
{
if (!fa.CanRemove())
throw new InvalidOperationException("Removing user flags is denied");
fa.OnRemoveUnsafe(Database, RemovingUser);
fa.OnRemoveUnsafe(database, UserService.CurrentUser);
}
public static void OnRemoveUnsafe(this UserFlagAssignment fa, DiscoDataContext Database, User RemovingUser)
public static void OnRemoveUnsafe(this UserFlagAssignment fa, DiscoDataContext database, User removingUser)
{
fa = Database.UserFlagAssignments.First(a => a.Id == fa.Id);
RemovingUser = Database.Users.First(u => u.UserId == RemovingUser.UserId);
fa = database.UserFlagAssignments.First(a => a.Id == fa.Id);
removingUser = database.Users.First(u => u.UserId == removingUser.UserId);
fa.RemovedDate = DateTime.Now;
fa.RemovedUserId = RemovingUser.UserId;
fa.RemovedUserId = removingUser.UserId;
if (!string.IsNullOrWhiteSpace(fa.UserFlag.OnUnassignmentExpression))
{
try
{
Database.SaveChanges();
var expressionResult = fa.EvaluateOnUnassignmentExpression(Database, RemovingUser, fa.AddedDate);
database.SaveChanges();
var expressionResult = fa.EvaluateOnUnassignmentExpression(database, removingUser, fa.AddedDate);
if (!string.IsNullOrWhiteSpace(expressionResult))
{
fa.OnUnassignmentExpressionResult = expressionResult;
Database.SaveChanges();
database.SaveChanges();
}
}
catch (Exception ex)
@@ -72,58 +77,52 @@ namespace Disco.Services
#endregion
#region Add
public static bool CanAddUserFlags(this User u)
{
return UserService.CurrentAuthorization.Has(Claims.User.Actions.AddFlags);
}
public static bool CanAddUserFlag(this User u, UserFlag flag)
{
// Shortcut
if (!u.CanAddUserFlags())
return false;
// Already has User Flag?
if (u.UserFlagAssignments.Any(fa => !fa.RemovedDate.HasValue && fa.UserFlagId == flag.Id))
return false;
return true;
var (_, permission) = UserFlagService.GetUserFlag(flag.Id);
return permission.CanAssign();
}
public static UserFlagAssignment OnAddUserFlag(this User u, DiscoDataContext Database, UserFlag flag, User AddingUser, string Comments)
public static UserFlagAssignment OnAddUserFlag(this User u, DiscoDataContext database, UserFlag flag, string comments)
{
if (!u.CanAddUserFlag(flag))
throw new InvalidOperationException("Adding user flag is denied");
return u.OnAddUserFlagUnsafe(Database, flag, AddingUser, Comments);
return u.OnAddUserFlagUnsafe(database, flag, UserService.CurrentUser, comments);
}
public static UserFlagAssignment OnAddUserFlagUnsafe(this User u, DiscoDataContext Database, UserFlag flag, User AddingUser, string Comments)
public static UserFlagAssignment OnAddUserFlagUnsafe(this User u, DiscoDataContext database, UserFlag flag, User addingUser, string comments)
{
flag = Database.UserFlags.First(f => f.Id == flag.Id);
u = Database.Users.First(user => user.UserId == u.UserId);
AddingUser = Database.Users.First(user => user.UserId == AddingUser.UserId);
flag = database.UserFlags.First(f => f.Id == flag.Id);
u = database.Users.First(user => user.UserId == u.UserId);
addingUser = database.Users.First(user => user.UserId == addingUser.UserId);
var fa = new UserFlagAssignment()
{
UserFlag = flag,
User = u,
AddedDate = DateTime.Now,
AddedUser = AddingUser,
AddedUserId = AddingUser.UserId,
Comments = string.IsNullOrWhiteSpace(Comments) ? null : Comments.Trim()
AddedUser = addingUser,
AddedUserId = addingUser.UserId,
Comments = string.IsNullOrWhiteSpace(comments) ? null : comments.Trim()
};
Database.UserFlagAssignments.Add(fa);
database.UserFlagAssignments.Add(fa);
if (!string.IsNullOrWhiteSpace(flag.OnAssignmentExpression))
{
try
{
Database.SaveChanges();
var expressionResult = fa.EvaluateOnAssignmentExpression(Database, AddingUser, fa.AddedDate);
database.SaveChanges();
var expressionResult = fa.EvaluateOnAssignmentExpression(database, addingUser, fa.AddedDate);
if (!string.IsNullOrWhiteSpace(expressionResult))
{
fa.OnAssignmentExpressionResult = expressionResult;
Database.SaveChanges();
database.SaveChanges();
}
}
catch (Exception ex)
@@ -5,6 +5,7 @@ using Disco.Services.Extensions;
using Disco.Services.Tasks;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Reactive.Linq;
@@ -12,7 +13,7 @@ namespace Disco.Services.Users.UserFlags
{
public static class UserFlagService
{
private static Cache _cache;
private static Cache cache;
internal static Lazy<IObservable<RepositoryMonitorEvent>> UserFlagAssignmentRepositoryEvents;
static UserFlagService()
@@ -24,25 +25,58 @@ namespace Disco.Services.Users.UserFlags
RepositoryMonitor.StreamAfterCommit.Where(e =>
e.EntityType == typeof(UserFlagAssignment) &&
(e.EventType != RepositoryMonitorEventType.Modified ||
e.ModifiedProperties.Contains("RemovedDate"))
e.ModifiedProperties.Contains(nameof(UserFlagAssignment.RemovedDate)))
)
);
}
public static void Initialize(DiscoDataContext Database)
{
_cache = new Cache(Database);
cache = new Cache(Database);
// Initialize Managed Groups (if configured)
_cache.GetUserFlags().ForEach(uf =>
cache.GetUserFlags().ForEach(uf =>
{
UserFlagUsersManagedGroup.Initialize(uf);
UserFlagUserDevicesManagedGroup.Initialize(uf);
UserFlagUsersManagedGroup.Initialize(uf.flag);
UserFlagUserDevicesManagedGroup.Initialize(uf.flag);
});
}
public static List<UserFlag> GetUserFlags() { return _cache.GetUserFlags(); }
public static UserFlag GetUserFlag(int UserFlagId) { return _cache.GetUserFlag(UserFlagId); }
public static IEnumerable<(UserFlag flag, FlagPermission permission)> GetUserFlags() { return cache.GetUserFlags(); }
public static (UserFlag flag, FlagPermission permission) GetUserFlag(int UserFlagId) { return cache.GetUserFlag(UserFlagId); }
public static UserFlag GetAvailableUserFlag(int userFlagId, User targetUser)
{
var (userFlag, permission) = cache.GetUserFlag(userFlagId);
if (targetUser.UserFlagAssignments
.Where(a => a.UserFlagId == userFlagId && !a.RemovedDate.HasValue).Any())
return null;
if (permission.CanAssign())
return userFlag;
return null;
}
public static IEnumerable<UserFlag> GetAvailableUserFlags(User targetUser)
{
var records = cache.GetUserFlags();
var usedFlags = targetUser.UserFlagAssignments
.Where(a => !a.RemovedDate.HasValue)
.Select(a => a.UserFlagId)
.ToList();
foreach (var (flag, permission) in records)
{
if (usedFlags.Contains(flag.Id))
continue;
if (permission.CanAssign())
yield return flag;
}
}
#region User Flag Maintenance
public static UserFlag CreateUserFlag(DiscoDataContext Database, string name, string description)
@@ -52,7 +86,7 @@ namespace Disco.Services.Users.UserFlags
throw new ArgumentException("The User Flag Name is required", nameof(name));
// Name Unique
if (_cache.GetUserFlags().Any(f => f.Name.Equals(name, StringComparison.Ordinal)))
if (cache.GetUserFlags().Any(f => f.flag.Name.Equals(name, StringComparison.Ordinal)))
throw new ArgumentException("Another User Flag already exists with that name", nameof(name));
// Clone to break reference
@@ -67,7 +101,7 @@ namespace Disco.Services.Users.UserFlags
Database.UserFlags.Add(flag);
Database.SaveChanges();
_cache.AddOrUpdate(flag);
cache.AddOrUpdate(flag);
return flag;
}
@@ -78,12 +112,12 @@ namespace Disco.Services.Users.UserFlags
throw new ArgumentException("The User Flag Name is required");
// Name Unique
if (_cache.GetUserFlags().Any(f => f.Id != UserFlag.Id && f.Name == UserFlag.Name))
throw new ArgumentException("Another User Flag already exists with that name", "UserFlag");
if (cache.GetUserFlags().Any(f => f.flag.Id != UserFlag.Id && f.flag.Name == UserFlag.Name))
throw new ArgumentException("Another User Flag already exists with that name", nameof(UserFlag));
Database.SaveChanges();
_cache.AddOrUpdate(UserFlag);
cache.AddOrUpdate(UserFlag);
UserFlagUsersManagedGroup.Initialize(UserFlag);
UserFlagUserDevicesManagedGroup.Initialize(UserFlag);
@@ -113,22 +147,22 @@ namespace Disco.Services.Users.UserFlags
Database.SaveChanges();
// Remove from Cache
_cache.Remove(UserFlagId);
cache.Remove(UserFlagId);
Status.Finished($"Successfully Deleted User Flag: '{flag.Name}' [{flag.Id}]");
}
#endregion
#region Bulk Assignment
public static IEnumerable<UserFlagAssignment> BulkAssignAddUsers(DiscoDataContext Database, UserFlag UserFlag, User Technician, string Comments, List<User> Users, IScheduledTaskStatus Status)
public static IEnumerable<UserFlagAssignment> BulkAssignAddUsers(DiscoDataContext database, UserFlag userFlag, User techUser, string comments, List<User> users, IScheduledTaskStatus status)
{
if (Users.Count > 0)
if (users.Count > 0)
{
double progressInterval;
const int databaseChunkSize = 100;
string comments = string.IsNullOrWhiteSpace(Comments) ? null : Comments.Trim();
comments = string.IsNullOrWhiteSpace(comments) ? null : comments.Trim();
var addUsers = Users.Where(u => !u.UserFlagAssignments.Any(a => a.UserFlagId == UserFlag.Id && !a.RemovedDate.HasValue)).ToList();
var addUsers = users.Where(u => !u.UserFlagAssignments.Any(a => a.UserFlagId == userFlag.Id && !a.RemovedDate.HasValue)).ToList();
progressInterval = (double)100 / addUsers.Count;
@@ -138,39 +172,39 @@ namespace Disco.Services.Users.UserFlags
var chunkResults = chunk.Select((user, index) =>
{
Status.UpdateStatus((chunkIndexOffset + index) * progressInterval, $"Assigning Flag: {user.ToString()}");
status.UpdateStatus((chunkIndexOffset + index) * progressInterval, $"Assigning Flag: {user}");
return user.OnAddUserFlag(Database, UserFlag, Technician, comments);
return user.OnAddUserFlagUnsafe(database, userFlag, techUser, comments);
}).ToList();
// Save Chunk Items to Database
Database.SaveChanges();
database.SaveChanges();
return chunkResults;
}).Where(fa => fa != null).ToList();
Status.SetFinishedMessage($"{addUsers.Count} Users/s Added; {(Users.Count - addUsers.Count)} User/s Skipped");
status.SetFinishedMessage($"{addUsers.Count} Users/s Added; {users.Count - addUsers.Count} User/s Skipped");
return addedUserAssignments;
}
else
{
Status.SetFinishedMessage("No changes found");
status.SetFinishedMessage("No changes found");
return Enumerable.Empty<UserFlagAssignment>();
}
}
public static IEnumerable<UserFlagAssignment> BulkAssignOverrideUsers(DiscoDataContext Database, UserFlag UserFlag, User Technician, string Comments, List<User> Users, IScheduledTaskStatus Status)
public static IEnumerable<UserFlagAssignment> BulkAssignOverrideUsers(DiscoDataContext database, UserFlag userFlag, User techUser, string comments, List<User> users, IScheduledTaskStatus status)
{
double progressInterval;
const int databaseChunkSize = 100;
string comments = string.IsNullOrWhiteSpace(Comments) ? null : Comments.Trim();
comments = string.IsNullOrWhiteSpace(comments) ? null : comments.Trim();
Status.UpdateStatus(0, "Calculating assignment changes");
status.UpdateStatus(0, "Calculating assignment changes");
var currentAssignments = Database.UserFlagAssignments.Include("User").Where(a => a.UserFlagId == UserFlag.Id && !a.RemovedDate.HasValue).ToList();
var removeAssignments = currentAssignments.Where(ca => !Users.Any(u => u.UserId.Equals(ca.UserId, StringComparison.OrdinalIgnoreCase))).ToList();
var addUsers = Users.Where(u => !currentAssignments.Any(ca => ca.UserId.Equals(u.UserId, StringComparison.OrdinalIgnoreCase))).ToList();
var currentAssignments = database.UserFlagAssignments.Include(a => a.User).Where(a => a.UserFlagId == userFlag.Id && !a.RemovedDate.HasValue).ToList();
var removeAssignments = currentAssignments.Where(ca => !users.Any(u => u.UserId.Equals(ca.UserId, StringComparison.OrdinalIgnoreCase))).ToList();
var addUsers = users.Where(u => !currentAssignments.Any(ca => ca.UserId.Equals(u.UserId, StringComparison.OrdinalIgnoreCase))).ToList();
if (removeAssignments.Count > 0 || addUsers.Count > 0)
{
@@ -184,15 +218,15 @@ namespace Disco.Services.Users.UserFlags
var chunkResults = chunk.Select((flagAssignment, index) =>
{
Status.UpdateStatus((chunkIndexOffset + index) * progressInterval, $"Removing Flag: {flagAssignment.User.ToString()}");
status.UpdateStatus((chunkIndexOffset + index) * progressInterval, $"Removing Flag: {flagAssignment.User}");
flagAssignment.OnRemoveUnsafe(Database, Technician);
flagAssignment.OnRemoveUnsafe(database, techUser);
return flagAssignment;
}).ToList();
// Save Chunk Items to Database
Database.SaveChanges();
database.SaveChanges();
return chunkResults;
}).ToList();
@@ -204,24 +238,24 @@ namespace Disco.Services.Users.UserFlags
var chunkResults = chunk.Select((user, index) =>
{
Status.UpdateStatus((chunkIndexOffset + index) * progressInterval, $"Assigning Flag: {user.ToString()}");
status.UpdateStatus((chunkIndexOffset + index) * progressInterval, string.Format("Assigning Flag: {0}", user.ToString()));
return user.OnAddUserFlag(Database, UserFlag, Technician, comments);
return user.OnAddUserFlagUnsafe(database, userFlag, techUser, comments);
}).ToList();
// Save Chunk Items to Database
Database.SaveChanges();
database.SaveChanges();
return chunkResults;
}).ToList();
Status.SetFinishedMessage($"{addUsers.Count} Users/s Added; {removeAssignments.Count} User/s Removed; {(Users.Count - addUsers.Count)} User/s Skipped");
status.SetFinishedMessage($"{addUsers.Count} Users/s Added; {removeAssignments.Count} User/s Removed; {users.Count - addUsers.Count} User/s Skipped");
return addedUserAssignments;
}
else
{
Status.SetFinishedMessage("No changes found");
status.SetFinishedMessage("No changes found");
return Enumerable.Empty<UserFlagAssignment>();
}
}
@@ -229,11 +263,11 @@ namespace Disco.Services.Users.UserFlags
public static string RandomUnusedIcon()
{
return UIHelpers.RandomIcon(_cache.GetUserFlags().Select(f => f.Icon));
return UIHelpers.RandomIcon(cache.GetUserFlags().Select(f => f.flag.Icon));
}
public static string RandomUnusedThemeColour()
{
return UIHelpers.RandomThemeColour(_cache.GetUserFlags().Select(f => f.IconColour));
return UIHelpers.RandomThemeColour(cache.GetUserFlags().Select(f => f.flag.IconColour));
}
}
}
+13 -5
View File
@@ -154,7 +154,7 @@ namespace Disco.Services.Users
AuthorizationLog.LogRoleCreated(role, CurrentUserId);
// Add to Cache
RoleCache.AddRole(role);
RoleCache.AddOrUpdateRole(role);
// Flush User Cache
Cache.FlushCache();
@@ -164,7 +164,7 @@ namespace Disco.Services.Users
public static void DeleteAuthorizationRole(DiscoDataContext Database, AuthorizationRole Role)
{
if (Role == null)
throw new ArgumentNullException("Role");
throw new ArgumentNullException(nameof(Role));
Database.AuthorizationRoles.Remove(Role);
Database.SaveChanges();
@@ -180,19 +180,27 @@ namespace Disco.Services.Users
public static void UpdateAuthorizationRole(DiscoDataContext Database, AuthorizationRole Role)
{
if (Role == null)
throw new ArgumentNullException("Role");
throw new ArgumentNullException(nameof(Role));
if (Database == null)
throw new ArgumentNullException("Database");
throw new ArgumentNullException(nameof(Database));
Database.SaveChanges();
// Update Role Cache
RoleCache.UpdateRole(Role);
RoleCache.AddOrUpdateRole(Role);
// Flush User Cache
Cache.FlushCache();
}
public static string GetAuthorizationRoleName(int roleId)
{
var role = RoleCache.GetRoleToken(roleId);
if (role == null)
return "Unknown authorization role";
return role.Role.Name;
}
public static IEnumerable<string> AdministratorSubjectIds
{
get
+8 -2
View File
@@ -12,7 +12,13 @@ namespace Disco.Services.Web
protected static HttpStatusCodeResult BadRequest(string message = null)
=> StatusCode(HttpStatusCode.BadRequest, message);
protected static HttpStatusCodeResult StatusCode(HttpStatusCode statusCode, string message = null)
=> new HttpStatusCodeResult(statusCode, message);
protected static HttpStatusCodeResult StatusCode(HttpStatusCode statusCode, string statusDescription = null)
=> new HttpStatusCodeResult(statusCode, statusDescription);
protected static HttpNotFoundResult NotFound(string statusDescription = null)
=> new HttpNotFoundResult(statusDescription);
protected static HttpUnauthorizedResult Unauthorized(string statusDescription = null)
=> new HttpUnauthorizedResult(statusDescription);
}
}
@@ -78,14 +78,16 @@ namespace Disco.Web.Areas.API.Controllers
}
}
private void UpdateClaims(AuthorizationRole AuthorizationRole, string[] ClaimKeys)
private void UpdateClaims(AuthorizationRole AuthorizationRole, string[] claimKeys)
{
var proposedClaims = Claims.BuildClaims(ClaimKeys);
claimKeys = claimKeys ?? Array.Empty<string>();
var proposedClaims = Claims.BuildClaims(claimKeys);
var currentToken = RoleToken.FromAuthorizationRole(AuthorizationRole);
var currentClaimKeys = Claims.GetClaimKeys(currentToken.Claims);
var removedClaims = currentClaimKeys.Except(ClaimKeys).ToArray();
var addedClaims = ClaimKeys.Except(currentClaimKeys).ToArray();
var removedClaims = currentClaimKeys.Except(claimKeys).ToArray();
var addedClaims = claimKeys.Except(currentClaimKeys).ToArray();
AuthorizationRole.SetClaims(proposedClaims);
UserService.UpdateAuthorizationRole(Database, AuthorizationRole);
@@ -1,6 +1,5 @@
using Disco.Models.Repository;
using Disco.Services;
using Disco.Services.Authorization;
using Disco.Services.Web;
using System;
using System.Data.Entity;
@@ -12,7 +11,7 @@ namespace Disco.Web.Areas.API.Controllers
public partial class DeviceFlagAssignmentController : AuthorizedDatabaseController
{
const string pComments = "comments";
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult Update(int id, string key, string value = null, bool? redirect = null)
{
try
@@ -21,7 +20,9 @@ namespace Disco.Web.Areas.API.Controllers
throw new ArgumentOutOfRangeException(nameof(id));
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
var assignment = Database.DeviceFlagAssignments.FirstOrDefault(a => a.Id == id);
var assignment = Database.DeviceFlagAssignments
.Include(a => a.DeviceFlag)
.FirstOrDefault(a => a.Id == id);
if (assignment != null)
{
switch (key.ToLower())
@@ -52,7 +53,7 @@ namespace Disco.Web.Areas.API.Controllers
}
#region Update Shortcut Methods
[DiscoAuthorizeAny(Claims.Device.Actions.EditFlags)]
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult UpdateComments(int id, string Comments = null, bool? redirect = null)
{
return Update(id, pComments, Comments, redirect);
@@ -60,20 +61,19 @@ namespace Disco.Web.Areas.API.Controllers
#endregion
#region Update Properties
private void UpdateComments(DeviceFlagAssignment assignment, string Comments)
private void UpdateComments(DeviceFlagAssignment assignment, string comments)
{
if (!assignment.CanEditComments())
if (!assignment.CanEdit())
throw new InvalidOperationException("Editing comments for device flags is denied");
assignment.OnEditComments(Comments);
assignment.OnEdit(comments);
Database.SaveChanges();
}
#endregion
#region Actions
[DiscoAuthorizeAny(Claims.Device.Actions.AddFlags)]
public virtual ActionResult AddDevice(int id, string DeviceSerialNumber, string Comments)
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult AddDevice(int id, string deviceSerialNumber, string comments)
{
Database.Configuration.LazyLoadingEnabled = true;
@@ -81,37 +81,35 @@ namespace Disco.Web.Areas.API.Controllers
if (flag == null)
throw new ArgumentException("Invalid Device Flag Id", nameof(id));
var device = Database.Devices.Include(u => u.DeviceFlagAssignments).FirstOrDefault(d => d.SerialNumber == DeviceSerialNumber);
var device = Database.Devices.Include(u => u.DeviceFlagAssignments).FirstOrDefault(d => d.SerialNumber == deviceSerialNumber);
if (device == null)
throw new ArgumentException("Invalid Device Serial Number", nameof(DeviceSerialNumber));
throw new ArgumentException("Invalid Device Serial Number", nameof(deviceSerialNumber));
if (!device.CanAddDeviceFlag(flag))
throw new InvalidOperationException("Adding device flag is denied");
return Unauthorized("Adding device flag is denied");
var addingUser = Database.Users.Find(CurrentUser.UserId);
var assignment = device.OnAddDeviceFlag(Database, flag, addingUser, Comments);
var assignment = device.OnAddDeviceFlag(Database, flag, comments);
Database.SaveChanges();
return Redirect($"{Url.Action(MVC.Device.Show(device.SerialNumber))}#DeviceDetailTab-Flags");
}
[DiscoAuthorizeAny(Claims.Device.Actions.RemoveFlags)]
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult RemoveDevice(int id)
{
Database.Configuration.LazyLoadingEnabled = true;
var assignment = Database.DeviceFlagAssignments.FirstOrDefault(a => a.Id == id);
var assignment = Database.DeviceFlagAssignments
.Include(a => a.DeviceFlag)
.FirstOrDefault(a => a.Id == id);
if (assignment == null)
throw new ArgumentException("Invalid Device Flag Assignment Id", nameof(id));
if (!assignment.CanRemove())
throw new InvalidOperationException("Removing device flag assignment is denied");
return Unauthorized("Removing device flag assignment is denied");
var removingUser = Database.Users.Find(CurrentUser.UserId);
assignment.OnRemove(Database, removingUser);
assignment.OnRemove(Database);
Database.SaveChanges();
return Redirect($"{Url.Action(MVC.Device.Show(assignment.DeviceSerialNumber))}#DeviceDetailTab-Flags");
@@ -5,7 +5,9 @@ using Disco.Services.Devices.DeviceFlags;
using Disco.Services.Exporting;
using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Tasks;
using Disco.Services.Users.UserFlags;
using Disco.Services.Web;
using Disco.Web.Areas.API.Models.Shared;
using Disco.Web.Areas.Config.Models.DeviceFlag;
using Disco.Web.Extensions;
using System;
@@ -467,6 +469,24 @@ namespace Disco.Web.Areas.API.Controllers
return RedirectToAction(MVC.Config.Export.Create(savedExport.Id));
}
[DiscoAuthorize(Claims.Config.DeviceFlag.Configure)]
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult Permission(int id, FlagPermissionModel model = null)
{
var deviceFlag = Database.DeviceFlags.Find(id);
if (deviceFlag == null)
return NotFound();
if (model == null || !model.IsOverride)
deviceFlag.Permissions = null;
else
deviceFlag.Permissions = model.ToFlagPermission(deviceFlag);
DeviceFlagService.Update(Database, deviceFlag);
return RedirectToAction(MVC.Config.DeviceFlag.Index(deviceFlag.Id));
}
#endregion
}
}
@@ -4,7 +4,9 @@ using Disco.Services.Authorization;
using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Interop.DiscoServices;
using Disco.Services.Messaging;
using Disco.Services.Users;
using Disco.Services.Web;
using Disco.Web.Areas.API.Models.Shared;
using System;
using System.Collections.Generic;
using System.Drawing;
@@ -320,38 +322,64 @@ namespace Disco.Web.Areas.API.Controllers
};
}
[DiscoAuthorizeAny(Claims.DiscoAdminAccount, Claims.Config.JobQueue.Configure)]
public virtual ActionResult SearchSubjects(string term)
[DiscoAuthorizeAny(Claims.DiscoAdminAccount, Claims.Config.JobQueue.Configure, Claims.Config.UserFlag.Configure, Claims.Config.DeviceFlag.Configure)]
public virtual ActionResult SearchSubjects(string term, bool includeAuthorizationRoles = false)
{
var groupResults = ActiveDirectory.SearchADGroups(term).Cast<IADObject>();
var userResults = ActiveDirectory.SearchADUserAccounts(term, true).Cast<IADObject>();
var groupResults = ActiveDirectory.SearchADGroups(term).Select(r => SubjectDescriptorModel.FromActiveDirectoryObject(r));
var userResults = ActiveDirectory.SearchADUserAccounts(term, true).Select(r => SubjectDescriptorModel.FromActiveDirectoryObject(r));
var results = groupResults.Concat(userResults).OrderBy(r => r.SamAccountName)
.Select(r => Models.Shared.SubjectDescriptorModel.FromActiveDirectoryObject(r)).ToList();
IEnumerable<SubjectDescriptorModel> roleResults;
if (includeAuthorizationRoles)
{
roleResults = Database.AuthorizationRoles.AsNoTracking().Where(r => r.Name.Contains(term))
.ToList()
.Select(r => SubjectDescriptorModel.FromAuthorizationRole(r));
}
else
roleResults = Enumerable.Empty<SubjectDescriptorModel>();
var results = groupResults.Concat(userResults).Concat(roleResults)
.OrderBy(r => r.Id).ToList();
return Json(results, JsonRequestBehavior.AllowGet);
}
[DiscoAuthorizeAny(Claims.Config.UserFlag.Configure)]
[DiscoAuthorizeAny(Claims.DiscoAdminAccount, Claims.Config.DeviceProfile.Configure, Claims.Config.DocumentTemplate.Configure, Claims.Config.Plugin.Configure, Claims.Config.UserFlag.Configure, Claims.Config.DeviceFlag.Configure)]
public virtual ActionResult SearchGroupSubjects(string term)
{
var groupResults = ActiveDirectory.SearchADGroups(term).Cast<IADObject>();
var results = groupResults.OrderBy(r => r.SamAccountName)
.Select(r => Models.Shared.SubjectDescriptorModel.FromActiveDirectoryObject(r)).ToList();
.Select(r => SubjectDescriptorModel.FromActiveDirectoryObject(r)).ToList();
return Json(results, JsonRequestBehavior.AllowGet);
}
[DiscoAuthorizeAny(Claims.DiscoAdminAccount, Claims.Config.JobQueue.Configure)]
public virtual ActionResult Subject(string Id)
[DiscoAuthorizeAny(Claims.DiscoAdminAccount, Claims.Config.JobQueue.Configure, Claims.Config.UserFlag.Configure, Claims.Config.DeviceFlag.Configure)]
public virtual ActionResult Subject(string Id, bool includeAuthorizationRoles = false)
{
if (string.IsNullOrWhiteSpace(Id))
return Json(null, JsonRequestBehavior.AllowGet);
if (Id.StartsWith("[", StringComparison.Ordinal))
{
if (includeAuthorizationRoles && int.TryParse(Id.Trim('[', ']'), out var roleId))
{
var roleName = UserService.GetAuthorizationRoleName(roleId);
if (roleName != null)
{
return Json(SubjectDescriptorModel.FromAuthorizationRole(roleId, roleName), JsonRequestBehavior.AllowGet);
}
}
return Json(null, JsonRequestBehavior.AllowGet);
}
var subject = ActiveDirectory.RetrieveADObject(Id, Quick: true);
if (subject == null)
return Json(null, JsonRequestBehavior.AllowGet);
else
return Json(Models.Shared.SubjectDescriptorModel.FromActiveDirectoryObject(subject), JsonRequestBehavior.AllowGet);
return Json(SubjectDescriptorModel.FromActiveDirectoryObject(subject), JsonRequestBehavior.AllowGet);
}
[DiscoAuthorizeAny(Claims.Config.UserFlag.Configure, Claims.Config.DeviceFlag.Configure, Claims.Config.DeviceProfile.Configure, Claims.Config.DocumentTemplate.Configure)]
@@ -12,7 +12,7 @@ namespace Disco.Web.Areas.API.Controllers
public partial class UserFlagAssignmentController : AuthorizedDatabaseController
{
const string pComments = "comments";
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult Update(int id, string key, string value = null, bool? redirect = null)
{
try
@@ -21,7 +21,9 @@ namespace Disco.Web.Areas.API.Controllers
throw new ArgumentOutOfRangeException(nameof(id));
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
var userFlagAssignment = Database.UserFlagAssignments.FirstOrDefault(a => a.Id == id);
var userFlagAssignment = Database.UserFlagAssignments
.Include(a => a.UserFlag)
.FirstOrDefault(a => a.Id == id);
if (userFlagAssignment != null)
{
switch (key.ToLower())
@@ -52,7 +54,7 @@ namespace Disco.Web.Areas.API.Controllers
}
#region Update Shortcut Methods
[DiscoAuthorizeAny(Claims.User.Actions.EditFlags)]
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult UpdateComments(int id, string Comments = null, bool? redirect = null)
{
return Update(id, pComments, Comments, redirect);
@@ -60,19 +62,19 @@ namespace Disco.Web.Areas.API.Controllers
#endregion
#region Update Properties
private void UpdateComments(UserFlagAssignment userFlagAssignment, string Comments)
private void UpdateComments(UserFlagAssignment userFlagAssignment, string comments)
{
if (!userFlagAssignment.CanEditComments())
if (!userFlagAssignment.CanEdit())
throw new InvalidOperationException("Editing comments for user flags is denied");
userFlagAssignment.OnEditComments(Comments);
userFlagAssignment.OnEdit(comments);
Database.SaveChanges();
}
#endregion
#region Actions
[DiscoAuthorizeAny(Claims.User.Actions.AddFlags)]
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult AddUser(int id, string UserId, string Comments)
{
Database.Configuration.LazyLoadingEnabled = true;
@@ -86,32 +88,30 @@ namespace Disco.Web.Areas.API.Controllers
throw new ArgumentException("Invalid User Id", nameof(UserId));
if (!user.CanAddUserFlag(userFlag))
throw new InvalidOperationException("Adding user flag is denied");
return Unauthorized("Adding user flag is denied");
var addingUser = Database.Users.Find(CurrentUser.UserId);
var userFlagAssignment = user.OnAddUserFlag(Database, userFlag, addingUser, Comments);
var userFlagAssignment = user.OnAddUserFlag(Database, userFlag, Comments);
Database.SaveChanges();
return Redirect($"{Url.Action(MVC.User.Show(user.UserId))}#UserDetailTab-Flags");
}
[DiscoAuthorizeAny(Claims.User.Actions.RemoveFlags)]
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult RemoveUser(int id)
{
Database.Configuration.LazyLoadingEnabled = true;
var userFlagAssignment = Database.UserFlagAssignments.FirstOrDefault(a => a.Id == id);
var userFlagAssignment = Database.UserFlagAssignments
.Include(a => a.UserFlag)
.FirstOrDefault(a => a.Id == id);
if (userFlagAssignment == null)
throw new ArgumentException("Invalid User Flag Assignment Id", nameof(id));
if (!userFlagAssignment.CanRemove())
throw new InvalidOperationException("Removing user flag assignment is denied");
return Unauthorized("Removing user flag assignment is denied");
var removingUser = Database.Users.Find(CurrentUser.UserId);
userFlagAssignment.OnRemove(Database, removingUser);
userFlagAssignment.OnRemove(Database);
Database.SaveChanges();
return Redirect($"{Url.Action(MVC.User.Show(userFlagAssignment.UserId))}#UserDetailTab-Flags");
@@ -6,6 +6,7 @@ using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Tasks;
using Disco.Services.Users.UserFlags;
using Disco.Services.Web;
using Disco.Web.Areas.API.Models.Shared;
using Disco.Web.Areas.Config.Models.UserFlag;
using Disco.Web.Extensions;
using System;
@@ -467,6 +468,24 @@ namespace Disco.Web.Areas.API.Controllers
return RedirectToAction(MVC.Config.Export.Create(savedExport.Id));
}
[DiscoAuthorize(Claims.Config.UserFlag.Configure)]
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult Permission(int id, FlagPermissionModel model = null)
{
var userFlag = Database.UserFlags.Find(id);
if (userFlag == null)
return NotFound();
if (model == null || !model.IsOverride)
userFlag.Permissions = null;
else
userFlag.Permissions = model.ToFlagPermission(userFlag);
UserFlagService.Update(Database, userFlag);
return RedirectToAction(MVC.Config.UserFlag.Index(userFlag.Id));
}
#endregion
}
}
@@ -0,0 +1,21 @@
using Disco.Models.Repository;
using System.Collections.Generic;
namespace Disco.Web.Areas.API.Models.Shared
{
public class FlagPermissionModel
{
public bool IsOverride { get; set; }
public bool Inherit { get; set; }
public List<string> CanShow { get; set; }
public List<string> CanAssign { get; set; }
public List<string> CanEdit { get; set; }
public List<string> CanRemove { get; set; }
public FlagPermission ToFlagPermission(UserFlag userFlag)
=> FlagPermission.Create(userFlag, Inherit, CanShow, CanAssign, CanEdit, CanRemove);
public FlagPermission ToFlagPermission(DeviceFlag deviceFlag)
=> FlagPermission.Create(deviceFlag, Inherit, CanShow, CanAssign, CanEdit, CanRemove);
}
}
@@ -1,4 +1,5 @@
using Disco.Services.Interop.ActiveDirectory;
using Disco.Models.Repository;
using Disco.Services.Interop.ActiveDirectory;
namespace Disco.Web.Areas.API.Models.Shared
{
@@ -43,5 +44,19 @@ namespace Disco.Web.Areas.API.Models.Shared
return item;
}
public static SubjectDescriptorModel FromAuthorizationRole(int roleId, string roleName)
{
return new SubjectDescriptorModel()
{
Id = $"[{roleId}]",
Name = roleName,
Type = "role",
IsGroup = true
};
}
public static SubjectDescriptorModel FromAuthorizationRole(AuthorizationRole role)
=> FromAuthorizationRole(role.Id, role.Name);
}
}
@@ -47,6 +47,9 @@ namespace Disco.Web.Areas.Config.Controllers
m.ThemeColours = UIHelpers.ThemeColours;
}
var (_, permission) = DeviceFlagService.GetDeviceFlag(m.DeviceFlag.Id);
m.Permission = permission;
// UI Extensions
UIExtensions.ExecuteExtensions<ConfigDeviceFlagShowModel>(ControllerContext, m);
@@ -121,7 +124,7 @@ namespace Disco.Web.Areas.Config.Controllers
var m = new ExportModel()
{
Options = Database.DiscoConfiguration.DeviceFlags.LastExportOptions,
DeviceFlags = DeviceFlagService.GetDeviceFlags(),
DeviceFlags = DeviceFlagService.GetDeviceFlags().Select(f => f.flag).ToList(),
};
m.Fields = ExportFieldsModel.Create(m.Options, DeviceFlagExportOptions.DefaultOptions(), nameof(DeviceFlagExportOptions.CurrentOnly));
@@ -46,6 +46,9 @@ namespace Disco.Web.Areas.Config.Controllers
m.ThemeColours = UIHelpers.ThemeColours;
}
var (flag, permission) = UserFlagService.GetUserFlag(m.UserFlag.Id);
m.Permission = permission;
// UI Extensions
UIExtensions.ExecuteExtensions<ConfigUserFlagShowModel>(ControllerContext, m);
@@ -122,7 +125,7 @@ namespace Disco.Web.Areas.Config.Controllers
var m = new ExportModel()
{
Options = Database.DiscoConfiguration.UserFlags.LastExportOptions,
UserFlags = UserFlagService.GetUserFlags(),
UserFlags = UserFlagService.GetUserFlags().Select(f => f.flag).ToList(),
};
m.Fields = ExportFieldsModel.Create(m.Options, UserFlagExportOptions.DefaultOptions(), nameof(UserFlagExportOptions.CurrentOnly));
@@ -1,4 +1,5 @@
using Disco.Models.UI.Config.DeviceFlag;
using Disco.Models.Repository;
using Disco.Models.UI.Config.DeviceFlag;
using Disco.Services.Devices.DeviceFlags;
using System.Collections.Generic;
@@ -16,5 +17,7 @@ namespace Disco.Web.Areas.Config.Models.DeviceFlag
public IEnumerable<KeyValuePair<string, string>> Icons { get; set; }
public IEnumerable<KeyValuePair<string, string>> ThemeColours { get; set; }
public FlagPermission Permission { get; set; }
}
}
@@ -1,4 +1,5 @@
using Disco.Models.UI.Config.UserFlag;
using Disco.Models.Repository;
using Disco.Models.UI.Config.UserFlag;
using Disco.Services.Users.UserFlags;
using System.Collections.Generic;
@@ -16,5 +17,7 @@ namespace Disco.Web.Areas.Config.Models.UserFlag
public IEnumerable<KeyValuePair<string, string>> Icons { get; set; }
public IEnumerable<KeyValuePair<string, string>> ThemeColours { get; set; }
public FlagPermission Permission { get; set; }
}
}
@@ -237,7 +237,7 @@
<div id="Config_AuthRoles_Claims_Tree">
</div>
<div>
<button type="button" id="Config_AuthRoles_Claims_SaveChanges" class="button small disabled" data-saveurl="@Url.Action(MVC.API.AuthorizationRole.UpdateClaims(Model.Token.Role.Id))">Save Changes</button>@AjaxHelpers.AjaxLoader()
<button type="button" typeof="button" id="Config_AuthRoles_Claims_SaveChanges" class="button small disabled" data-saveurl="@Url.Action(MVC.API.AuthorizationRole.UpdateClaims(Model.Token.Role.Id))">Save Changes</button>@AjaxHelpers.AjaxLoader()
</div>
<script id="Config_AuthRoles_Claims_NodesJson" type="application/json">
@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.ClaimNavigatorFancyTreeNodes))
@@ -286,7 +286,7 @@
saveButton.addClass('disabled');
ajaxLoading.next('.ajaxOk').show().delay('fast').fadeOut('slow');
} else {
alert('Unable to save changes:\n' + response);
alert('Unable to save changes:\n' + response.statusText);
}
} catch (e) {
alert('Error: ' + e);
@@ -656,6 +656,8 @@ WriteLiteral(">\r\n </div>\r\n <div>\r\n
WriteLiteral(" type=\"button\"");
WriteLiteral(" typeof=\"button\"");
WriteLiteral(" id=\"Config_AuthRoles_Claims_SaveChanges\"");
WriteLiteral(" class=\"button small disabled\"");
@@ -664,7 +666,7 @@ WriteLiteral(" data-saveurl=\"");
#line 240 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml"
Write(Url.Action(MVC.API.AuthorizationRole.UpdateClaims(Model.Token.Role.Id)));
Write(Url.Action(MVC.API.AuthorizationRole.UpdateClaims(Model.Token.Role.Id)));
#line default
@@ -675,7 +677,7 @@ WriteLiteral(">Save Changes</button>");
#line 240 "..\..\Areas\Config\Views\AuthorizationRole\Show.cshtml"
Write(AjaxHelpers.AjaxLoader());
Write(AjaxHelpers.AjaxLoader());
#line default
@@ -728,13 +730,13 @@ WriteLiteral("\r\n </script>\r\n <script>\r\n
"dClass(\'disabled\');\r\n ajaxLoading.nex" +
"t(\'.ajaxOk\').show().delay(\'fast\').fadeOut(\'slow\');\r\n " +
" } else {\r\n alert(\'Unable " +
"to save changes:\\n\' + response);\r\n }\r\n " +
" } catch (e) {\r\n " +
" alert(\'Error: \' + e);\r\n }\r\n " +
" ajaxLoading.hide();\r\n }" +
"\r\n });\r\n });\r\n " +
" })();\r\n </script>\r\n </td>\r\n </tr>\r\n </ta" +
"ble>\r\n</div>\r\n<div");
"to save changes:\\n\' + response.statusText);\r\n " +
" }\r\n } catch (e) {\r\n " +
" alert(\'Error: \' + e);\r\n }\r" +
"\n ajaxLoading.hide();\r\n " +
" }\r\n });\r\n });\r\n " +
" })();\r\n </script>\r\n </td>\r\n </tr" +
">\r\n </table>\r\n</div>\r\n<div");
WriteLiteral(" class=\"actionBar\"");
@@ -15,6 +15,7 @@
var canExportAll = Model.TotalAssignmentCount > 0 && Authorization.Has(Claims.Config.DeviceFlag.Export);
var hideAdvanced =
Model.Permission.IsDefault() &&
Model.DeviceFlag.DevicesLinkedGroup == null &&
Model.DeviceFlag.DeviceUsersLinkedGroup == null &&
Model.DeviceFlag.OnAssignmentExpression == null &&
@@ -38,10 +39,11 @@
</th>
<td>
@if (canConfig)
{@Html.EditorFor(model => model.DeviceFlag.Name)
@AjaxHelpers.AjaxSave()
@AjaxHelpers.AjaxLoader()
<script type="text/javascript">
{
@Html.EditorFor(model => model.DeviceFlag.Name)
@AjaxHelpers.AjaxSave()
@AjaxHelpers.AjaxLoader()
<script type="text/javascript">
$(function () {
document.DiscoFunctions.PropertyChangeHelper(
$('#DeviceFlag_Name'),
@@ -50,12 +52,12 @@
'FlagName'
);
});
</script>
}
else
{
@Model.DeviceFlag.Name
}
</script>
}
else
{
@Model.DeviceFlag.Name
}
</td>
</tr>
<tr>
@@ -227,6 +229,340 @@
</td>
</tr>
}
<tr class="Config_HideAdvanced_Item">
<th>
Assignment Permission<br />
Override:
</th>
<td>
@if (!Model.Permission.IsDefault())
{
var permission = Model.Permission;
<div>
@if (permission.Inherit)
{
<span><i class="fa fa-check-square-o"></i> Inheriting from Authorization Roles</span>
}
else
{
<span><i class="fa fa-square-o"></i> Authorization Roles are Ignored</span>
}
</div>
if (!permission.HasSubjects())
{
<span class="smallMessage">There are no users/groups associated with this permission override</span>
}
else
{
if (permission.IsSimple())
{
<table class="tableData">
<thead>
<tr>
<th>Users/Groups/Roles</th>
</tr>
</thead>
<tbody>
@foreach (var subjectId in permission.CanShowSubjectIds)
{
<tr>
<td>
@{
int roleId;
if (subjectId.StartsWith("[") && int.TryParse(subjectId.Trim('[', ']'), out roleId))
{
<span>@Disco.Services.Users.UserService.GetAuthorizationRoleName(roleId) @subjectId</span>
}
else
{
<span>@subjectId</span>
}
}
</td>
</tr>
}
</tbody>
</table>
<div class="info-box">
<p class="fa-p">
<i class="fa fa-fw fa-info-circle"></i> All users/groups/roles can view, assign, edit assignments, and remove assignments for this flag.
</p>
</div>
}
else
{
var subjects = permission.AllSubjects();
<table class="tableData">
<thead>
<tr>
<th>Users/Groups/Roles</th>
<th>View</th>
<th>Assign</th>
<th>Edit</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
@foreach (var subjectId in subjects.OrderBy(s => s))
{
<tr>
<td>
<i class="fa"></i> @{
int roleId;
if (subjectId.StartsWith("[") && int.TryParse(subjectId.Trim('[', ']'), out roleId))
{
<span>@Disco.Services.Users.UserService.GetAuthorizationRoleName(roleId) @subjectId</span>
}
else
{
<span>@subjectId</span>
}
}
</td>
<td>
@if (permission.CanShowSubjectIds.Contains(subjectId))
{
<i class="fa fa-fw fa-check"></i>
}
</td>
<td>
@if (permission.CanAssignSubjectIds.Contains(subjectId))
{
<i class="fa fa-fw fa-check"></i>
}
</td>
<td>
@if (permission.CanEditSubjectIds.Contains(subjectId))
{
<i class="fa fa-fw fa-check"></i>
}
</td>
<td>
@if (permission.CanRemoveSubjectIds.Contains(subjectId))
{
<i class="fa fa-fw fa-check"></i>
}
</td>
</tr>
}
</tbody>
</table>
}
}
}
@if (canConfig)
{
var permission = Model.Permission;
<button id="Config_Flag_Permission_Edit" class="button small">@(permission.IsDefault() ? "Override" : "Edit") Permission</button>
<div id="Config_Flag_Permissions" class="dialog" title="Flag Assignment Permission Override">
@using (Html.BeginForm(MVC.API.DeviceFlag.Permission(Model.DeviceFlag.Id)))
{
@Html.AntiForgeryToken()
<input type="hidden" name="IsOverride" value="true" />
<div id="Config_Flag_Permissions_Inherit_Container">
<label>
<input id="Config_Flag_Permissions_Inherit" type="checkbox" name="Inherit" value="true" @(permission.Inherit ? "checked" : null) /> Inherit Authorization from Authorization Roles
</label>
</div>
<div class="tableDataContainer">
<table class="tableData">
<thead>
<tr>
<th>User/Group/Role</th>
<th>View</th>
<th>Assign</th>
<th>Edit</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
@{
var subjects = permission.AllSubjects();
foreach (var subjectId in subjects.OrderBy(s => s))
{
<tr data-subjectid="@subjectId">
<td><i class="fa type"></i> <span>@subjectId</span><i class="fa fa-times-circle remove"></i></td>
<td>
<input type="checkbox" name="CanShow" value="@subjectId" @(permission.CanShowSubjectIds.Contains(subjectId) ? " checked" : null) />
</td>
<td>
<input type="checkbox" name="CanAssign" value="@subjectId" @(permission.CanAssignSubjectIds.Contains(subjectId) ? " checked" : null) />
</td>
<td>
<input type="checkbox" name="CanEdit" value="@subjectId" @(permission.CanEditSubjectIds.Contains(subjectId) ? " checked" : null) />
</td>
<td>
<input type="checkbox" name="CanRemove" value="@subjectId" @(permission.CanRemoveSubjectIds.Contains(subjectId) ? " checked" : null) />
</td>
</tr>
}
}
</tbody>
</table>
</div>
<div>
<input type="text" id="Config_Flag_Permissions_Subject_Input" placeholder="Search Users/Groups/Roles" data-autocompleteurl="@(Url.Action(MVC.API.System.SearchSubjects(null, includeAuthorizationRoles: true)))" />
<button type="button" id="Config_Flag_Permissions_Subject_Add" class="button small" data-subjecturl="@Url.Action(MVC.API.System.Subject(null, includeAuthorizationRoles: true))">Add</button>
</div>
}
</div>
<script>
$(function () {
let $dialog = null;
let originalSubjects = null;
let originalInherit = null;
$('#Config_Flag_Permission_Edit').on('click', async function () {
if (!$dialog) {
$dialog = $('#Config_Flag_Permissions');
const $tbody = $dialog.find('tbody');
const $inherit = $dialog.find('#Config_Flag_Permissions_Inherit');
const $input = $dialog.find('#Config_Flag_Permissions_Subject_Input');
const $add = $dialog.find('#Config_Flag_Permissions_Subject_Add');
$dialog.dialog({
resizable: false,
modal: true,
autoOpen: false,
width: 550,
height: 420,
buttons: {
Cancel: function () {
$(this).dialog('close');
$tbody.html(originalSubjects);
$inherit.prop('checked', originalInherit);
},
'Remove Override': function () {
const $this = $(this);
$(this).dialog('option', 'buttons', null);
$this.find('input[name="IsOverride"]').val('false');
$this.find('form').trigger('submit');
},
'Save Changes': function () {
$(this).dialog('option', 'buttons', null);
$(this).find('form').trigger('submit');
}
}
});
$tbody.on('click', 'i.remove', function () {
$(this).closest('tr').remove();
});
$input
.autocomplete({
source: $input.attr('data-autocompleteurl'),
minLength: 2,
focus: function (e, ui) {
$input.val(ui.item.Id);
return false;
},
select: function (e, ui) {
$input.val(ui.item.Id).blur();
$add.trigger('click');
$input.val('');
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);
};
$add.on('click', async function () {
const value = $input.val();
if (!value) {
$input.focus();
return;
}
const existing = $tbody.find('tr').filter(function () {
return $(this).attr('data-subjectid') === value;
});
if (existing.length !== 0) {
$input.val('');
$input.focus();
return;
}
const body = new FormData();
body.append('id', value);
const response = await fetch($add.attr('data-subjecturl'), {
body: body,
method: 'POST'
});
if (!response.ok) {
alert('Unable to lookup User/Group/Role: ' + response.statusText);
$input.focus();
return;
}
const subject = await response.json();
if (!subject) {
alert('Invalid User/Group/Role');
$input.focus();
return;
}
const $record = $('<tr><td><i class="fa type"></i> <span></span><i class="fa fa-times-circle remove"></i></td><td><input type="checkbox" name="CanShow" checked /></td><td><input type="checkbox" name="CanAssign" checked /></td><td><input type="checkbox" name="CanEdit" checked /></td><td><input type="checkbox" name="CanRemove" checked /></td></tr>');
$record.attr('data-subjectid', subject.Id);
$record.find('span').text(subject.Name + ' ' + subject.Id);
$record.find('i.type').addClass(subject.Type === 'role' ? 'fa-lock' : subject.IsGroup ? 'fa-users' : 'fa-user');
$record.find('input').val(subject.Id);
$tbody.append($record);
$input.val('');
$input.focus();
});
const $records = $tbody.find('tr');
for (var i = 0; i < $records.length; i++) {
const $record = $($records[i]);
const body = new FormData();
body.append('id', $record.attr('data-subjectid'));
const response = await fetch($add.attr('data-subjecturl'), {
body: body,
method: 'POST'
});
if (response.ok) {
const subject = await response.json();
if (subject) {
$record.find('span').text(subject.Name + ' ' + subject.Id);
$record.find('i.type').addClass(subject.Type === 'role' ? 'fa-lock' : subject.IsGroup ? 'fa-users' : 'fa-user');
continue;
}
}
$record.remove();
}
originalInherit = $inherit.prop('checked');
originalSubjects = $tbody.html();
$dialog.dialog('open');
} else {
$dialog.dialog('open');
}
});
});
</script>
}
<div class="info-box">
<p class="fa-p">
<i class="fa fa-fw fa-info-circle"></i> Flag actions are normally authorized globally by
@if (Authorization.Has(Claims.DiscoAdminAccount))
{
<span><a href="@Url.Action(MVC.Config.AuthorizationRole.Index(null))">Authorization Roles</a>.</span>
}
else
{
<span>Authorization Roles.</span>
}
Overriding individual flag permissions allows for targeted authorization.
</p>
</div>
</td>
</tr>
<tr class="Config_HideAdvanced_Item">
<th>
On Assignment<br />Expression:
File diff suppressed because it is too large Load Diff
@@ -15,6 +15,7 @@
var canExportAll = Model.TotalAssignmentCount > 0 && Authorization.Has(Claims.Config.UserFlag.Export);
var hideAdvanced =
Model.Permission.IsDefault() &&
Model.UserFlag.UserDevicesLinkedGroup == null &&
Model.UserFlag.UsersLinkedGroup == null &&
Model.UserFlag.OnAssignmentExpression == null &&
@@ -229,6 +230,340 @@
</td>
</tr>
}
<tr class="Config_HideAdvanced_Item">
<th>
Assignment Permission<br />
Override:
</th>
<td>
@if (!Model.Permission.IsDefault())
{
var permission = Model.Permission;
<div>
@if (permission.Inherit)
{
<span><i class="fa fa-check-square-o"></i> Inheriting from Authorization Roles</span>
}
else
{
<span><i class="fa fa-square-o"></i> Authorization Roles are Ignored</span>
}
</div>
if (!permission.HasSubjects())
{
<span class="smallMessage">There are no users/groups associated with this permission override</span>
}
else
{
if (permission.IsSimple())
{
<table class="tableData">
<thead>
<tr>
<th>Users/Groups/Roles</th>
</tr>
</thead>
<tbody>
@foreach (var subjectId in permission.CanShowSubjectIds)
{
<tr>
<td>
@{
int roleId;
if (subjectId.StartsWith("[") && int.TryParse(subjectId.Trim('[', ']'), out roleId))
{
<span>@Disco.Services.Users.UserService.GetAuthorizationRoleName(roleId) @subjectId</span>
}
else
{
<span>@subjectId</span>
}
}
</td>
</tr>
}
</tbody>
</table>
<div class="info-box">
<p class="fa-p">
<i class="fa fa-fw fa-info-circle"></i> All users/groups/roles can view, assign, edit assignments, and remove assignments for this flag.
</p>
</div>
}
else
{
var subjects = permission.AllSubjects();
<table class="tableData">
<thead>
<tr>
<th>Users/Groups/Roles</th>
<th>View</th>
<th>Assign</th>
<th>Edit</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
@foreach (var subjectId in subjects.OrderBy(s => s))
{
<tr>
<td>
<i class="fa"></i> @{
int roleId;
if (subjectId.StartsWith("[") && int.TryParse(subjectId.Trim('[', ']'), out roleId))
{
<span>@Disco.Services.Users.UserService.GetAuthorizationRoleName(roleId) @subjectId</span>
}
else
{
<span>@subjectId</span>
}
}
</td>
<td>
@if (permission.CanShowSubjectIds.Contains(subjectId))
{
<i class="fa fa-fw fa-check"></i>
}
</td>
<td>
@if (permission.CanAssignSubjectIds.Contains(subjectId))
{
<i class="fa fa-fw fa-check"></i>
}
</td>
<td>
@if (permission.CanEditSubjectIds.Contains(subjectId))
{
<i class="fa fa-fw fa-check"></i>
}
</td>
<td>
@if (permission.CanRemoveSubjectIds.Contains(subjectId))
{
<i class="fa fa-fw fa-check"></i>
}
</td>
</tr>
}
</tbody>
</table>
}
}
}
@if (canConfig)
{
var permission = Model.Permission;
<button id="Config_Flag_Permission_Edit" class="button small">@(permission.IsDefault() ? "Override" : "Edit") Permission</button>
<div id="Config_Flag_Permissions" class="dialog" title="Flag Assignment Permission Override">
@using (Html.BeginForm(MVC.API.UserFlag.Permission(Model.UserFlag.Id)))
{
@Html.AntiForgeryToken()
<input type="hidden" name="IsOverride" value="true" />
<div id="Config_Flag_Permissions_Inherit_Container">
<label>
<input id="Config_Flag_Permissions_Inherit" type="checkbox" name="Inherit" value="true" @(permission.Inherit ? "checked" : null) /> Inherit Authorization from Authorization Roles
</label>
</div>
<div class="tableDataContainer">
<table class="tableData">
<thead>
<tr>
<th>User/Group/Role</th>
<th>View</th>
<th>Assign</th>
<th>Edit</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
@{
var subjects = permission.AllSubjects();
foreach (var subjectId in subjects.OrderBy(s => s))
{
<tr data-subjectid="@subjectId">
<td><i class="fa type"></i> <span>@subjectId</span><i class="fa fa-times-circle remove"></i></td>
<td>
<input type="checkbox" name="CanShow" value="@subjectId" @(permission.CanShowSubjectIds.Contains(subjectId) ? " checked" : null) />
</td>
<td>
<input type="checkbox" name="CanAssign" value="@subjectId" @(permission.CanAssignSubjectIds.Contains(subjectId) ? " checked" : null) />
</td>
<td>
<input type="checkbox" name="CanEdit" value="@subjectId" @(permission.CanEditSubjectIds.Contains(subjectId) ? " checked" : null) />
</td>
<td>
<input type="checkbox" name="CanRemove" value="@subjectId" @(permission.CanRemoveSubjectIds.Contains(subjectId) ? " checked" : null) />
</td>
</tr>
}
}
</tbody>
</table>
</div>
<div>
<input type="text" id="Config_Flag_Permissions_Subject_Input" placeholder="Search Users/Groups" data-autocompleteurl="@(Url.Action(MVC.API.System.SearchSubjects(null, includeAuthorizationRoles: true)))" />
<button type="button" id="Config_Flag_Permissions_Subject_Add" class="button small" data-subjecturl="@Url.Action(MVC.API.System.Subject(null, includeAuthorizationRoles: true))">Add</button>
</div>
}
</div>
<script>
$(function () {
let $dialog = null;
let originalSubjects = null;
let originalInherit = null;
$('#Config_Flag_Permission_Edit').on('click', async function () {
if (!$dialog) {
$dialog = $('#Config_Flag_Permissions');
const $tbody = $dialog.find('tbody');
const $inherit = $dialog.find('#Config_Flag_Permissions_Inherit');
const $input = $dialog.find('#Config_Flag_Permissions_Subject_Input');
const $add = $dialog.find('#Config_Flag_Permissions_Subject_Add');
$dialog.dialog({
resizable: false,
modal: true,
autoOpen: false,
width: 550,
height: 420,
buttons: {
Cancel: function () {
$(this).dialog('close');
$tbody.html(originalSubjects);
$inherit.prop('checked', originalInherit);
},
'Remove Override': function () {
const $this = $(this);
$(this).dialog('option', 'buttons', null);
$this.find('input[name="IsOverride"]').val('false');
$this.find('form').trigger('submit');
},
'Save Changes': function () {
$(this).dialog('option', 'buttons', null);
$(this).find('form').trigger('submit');
}
}
});
$tbody.on('click', 'i.remove', function () {
$(this).closest('tr').remove();
});
$input
.autocomplete({
source: $input.attr('data-autocompleteurl'),
minLength: 2,
focus: function (e, ui) {
$input.val(ui.item.Id);
return false;
},
select: function (e, ui) {
$input.val(ui.item.Id).blur();
$add.trigger('click');
$input.val('');
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);
};
$add.on('click', async function () {
const value = $input.val();
if (!value) {
$input.focus();
return;
}
const existing = $tbody.find('tr').filter(function () {
return $(this).attr('data-subjectid') === value;
});
if (existing.length !== 0) {
$input.val('');
$input.focus();
return;
}
const body = new FormData();
body.append('id', value);
const response = await fetch($add.attr('data-subjecturl'), {
body: body,
method: 'POST'
});
if (!response.ok) {
alert('Unable to lookup User/Group/Role: ' + response.statusText);
$input.focus();
return;
}
const subject = await response.json();
if (!subject) {
alert('Invalid User/Group');
$input.focus();
return;
}
const $record = $('<tr><td><i class="fa type"></i> <span></span><i class="fa fa-times-circle remove"></i></td><td><input type="checkbox" name="CanShow" checked /></td><td><input type="checkbox" name="CanAssign" checked /></td><td><input type="checkbox" name="CanEdit" checked /></td><td><input type="checkbox" name="CanRemove" checked /></td></tr>');
$record.attr('data-subjectid', subject.Id);
$record.find('span').text(subject.Name + ' ' + subject.Id);
$record.find('i.type').addClass(subject.Type === 'role' ? 'fa-lock' : subject.IsGroup ? 'fa-users' : 'fa-user');
$record.find('input').val(subject.Id);
$tbody.append($record);
$input.val('');
$input.focus();
});
const $records = $tbody.find('tr');
for (var i = 0; i < $records.length; i++) {
const $record = $($records[i]);
const body = new FormData();
body.append('id', $record.attr('data-subjectid'));
const response = await fetch($add.attr('data-subjecturl'), {
body: body,
method: 'POST'
});
if (response.ok) {
const subject = await response.json();
if (subject) {
$record.find('span').text(subject.Name + ' ' + subject.Id);
$record.find('i.type').addClass(subject.Type === 'role' ? 'fa-lock' : subject.IsGroup ? 'fa-users' : 'fa-user');
continue;
}
}
$record.remove();
}
originalInherit = $inherit.prop('checked');
originalSubjects = $tbody.html();
$dialog.dialog('open');
} else {
$dialog.dialog('open');
}
});
});
</script>
}
<div class="info-box">
<p class="fa-p">
<i class="fa fa-fw fa-info-circle"></i> Flag actions are normally authorized globally by
@if (Authorization.Has(Claims.DiscoAdminAccount))
{
<span><a href="@Url.Action(MVC.Config.AuthorizationRole.Index(null))">Authorization Roles</a>.</span>
}
else
{
<span>Authorization Roles.</span>
}
Overriding individual flag permissions allows for targeted authorization.
</p>
</div>
</td>
</tr>
<tr class="Config_HideAdvanced_Item">
<th>
On Assignment<br />Expression:
@@ -369,7 +704,6 @@
</div>
</td>
</tr>
<tr class="Config_HideAdvanced_Item">
<th>
Linked Groups:
File diff suppressed because it is too large Load Diff
+17
View File
@@ -1960,6 +1960,23 @@ h1.Config_DocumentTemplates {
#Config_DeviceFlags_BulkAssign_AssignDialog.loading > form {
display: none;
}
#Config_Flag_Permissions #Config_Flag_Permissions_Inherit_Container {
margin: 5px 0;
}
#Config_Flag_Permissions .tableDataContainer {
min-height: 260px;
}
#Config_Flag_Permissions .tableDataContainer td i.remove {
float: right;
cursor: pointer;
visibility: hidden;
color: #e51400;
font-size: 1.4em;
opacity: 0.8;
}
#Config_Flag_Permissions .tableDataContainer td:hover i.remove {
visibility: visible;
}
#DocumentTemplate_BulkGenerate .actions {
padding-bottom: 0.5em;
text-align: right;
+27
View File
@@ -2354,6 +2354,33 @@ h1.Config_DocumentTemplates {
}
}
#Config_Flag_Permissions {
#Config_Flag_Permissions_Inherit_Container {
margin: 5px 0;
}
.tableDataContainer {
min-height: 260px;
td {
i.remove {
float: right;
cursor: pointer;
visibility: hidden;
color: @StatusRemove;
font-size: 1.4em;
opacity: .8;
}
}
td:hover {
i.remove {
visibility: visible;
}
}
}
}
#DocumentTemplate_BulkGenerate {
.actions {
padding-bottom: .5em;
File diff suppressed because one or more lines are too long
+2 -9
View File
@@ -235,6 +235,7 @@ namespace Disco.Web.Controllers
.Include(d => d.DeviceCertificates)
.Include(d => d.DeviceAttachments.Select(a => a.TechUser))
.Include(d => d.DeviceAttachments.Select(a => a.DocumentTemplate))
.Include(d => d.DeviceFlagAssignments.Select(a => a.DeviceFlag))
.Include(d => d.DeviceFlagAssignments.Select(a => a.AddedUser))
.Include(d => d.DeviceFlagAssignments.Select(a => a.RemovedUser))
.FirstOrDefault(d => d.SerialNumber == id);
@@ -311,15 +312,7 @@ namespace Disco.Web.Controllers
m.DeviceProfileWirelessProfileProviders = m.Device.DeviceProfile.GetWirelessProfileProviders().ToList();
}
if (Authorization.Has(Claims.Device.ShowFlagAssignments))
{
var usedFlags = m.Device.DeviceFlagAssignments
.Where(a => !a.RemovedDate.HasValue)
.Select(a => a.DeviceFlagId)
.Distinct().ToList();
m.AvailableDeviceFlags = DeviceFlagService.GetDeviceFlags().Where(f => !usedFlags.Contains(f.Id)).ToList();
}
m.AvailableDeviceFlags = DeviceFlagService.GetAvailableDeviceFlags(m.Device).ToList();
if (Authorization.Has(Claims.User.ShowDetails))
{
+2 -9
View File
@@ -61,6 +61,7 @@ namespace Disco.Web.Controllers
.Include(u => u.DeviceUserAssignments.Select(dua => dua.Device.DeviceDetails))
.Include(u => u.UserAttachments.Select(ua => ua.TechUser))
.Include(u => u.UserAttachments.Select(ua => ua.DocumentTemplate))
.Include(u => u.UserFlagAssignments.Select(ufa => ufa.UserFlag))
.Include(u => u.UserFlagAssignments.Select(ufa => ufa.AddedUser))
.Include(u => u.UserFlagAssignments.Select(ufa => ufa.RemovedUser))
.Include(u => u.UserDetails)
@@ -84,15 +85,7 @@ namespace Disco.Web.Controllers
m.Jobs.Fill(Database, Services.Searching.Search.BuildJobTableModel(Database).Where(j => j.UserId == id).OrderByDescending(j => j.Id), true);
}
if (Authorization.Has(Claims.User.ShowFlagAssignments))
{
var usedFlags = m.User.UserFlagAssignments
.Where(a => !a.RemovedDate.HasValue)
.Select(a => a.UserFlagId)
.Distinct().ToList();
m.AvailableUserFlags = UserFlagService.GetUserFlags().Where(f => !usedFlags.Contains(f.Id)).ToList();
}
m.AvailableUserFlags = UserFlagService.GetAvailableUserFlags(m.User).ToList();
try
{
+1
View File
@@ -227,6 +227,7 @@
<Compile Include="Areas\API\Models\Job\DeviceHeldLocationModel.cs" />
<Compile Include="Areas\API\Models\Shared\SubjectDescriptorModel.cs" />
<Compile Include="Areas\API\Models\System\DomainOrganisationalUnitsModel.cs" />
<Compile Include="Areas\API\Models\Shared\FlagPermissionModel.cs" />
<Compile Include="Areas\API\Views\_ViewStart.generated.cs">
<DependentUpon>_ViewStart.cshtml</DependentUpon>
<AutoGen>True</AutoGen>
@@ -143,8 +143,8 @@ namespace Disco.Web.Areas.API.Controllers
public class ActionParamsClass_AddDevice
{
public readonly string id = "id";
public readonly string DeviceSerialNumber = "DeviceSerialNumber";
public readonly string Comments = "Comments";
public readonly string deviceSerialNumber = "deviceSerialNumber";
public readonly string comments = "comments";
}
static readonly ActionParamsClass_RemoveDevice s_params_RemoveDevice = new ActionParamsClass_RemoveDevice();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
@@ -203,16 +203,16 @@ namespace Disco.Web.Areas.API.Controllers
}
[NonAction]
partial void AddDeviceOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id, string DeviceSerialNumber, string Comments);
partial void AddDeviceOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id, string deviceSerialNumber, string comments);
[NonAction]
public override System.Web.Mvc.ActionResult AddDevice(int id, string DeviceSerialNumber, string Comments)
public override System.Web.Mvc.ActionResult AddDevice(int id, string deviceSerialNumber, string comments)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AddDevice);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "DeviceSerialNumber", DeviceSerialNumber);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Comments", Comments);
AddDeviceOverride(callInfo, id, DeviceSerialNumber, Comments);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "deviceSerialNumber", deviceSerialNumber);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "comments", comments);
AddDeviceOverride(callInfo, id, deviceSerialNumber, comments);
return callInfo;
}
@@ -155,6 +155,12 @@ namespace Disco.Web.Areas.API.Controllers
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.SaveExport);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult Permission()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Permission);
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public DeviceFlagController Actions { get { return MVC.API.DeviceFlag; } }
@@ -187,6 +193,7 @@ namespace Disco.Web.Areas.API.Controllers
public readonly string Export = "Export";
public readonly string ExportRetrieve = "ExportRetrieve";
public readonly string SaveExport = "SaveExport";
public readonly string Permission = "Permission";
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
@@ -208,6 +215,7 @@ namespace Disco.Web.Areas.API.Controllers
public const string Export = "Export";
public const string ExportRetrieve = "ExportRetrieve";
public const string SaveExport = "SaveExport";
public const string Permission = "Permission";
}
@@ -367,6 +375,15 @@ namespace Disco.Web.Areas.API.Controllers
{
public readonly string model = "model";
}
static readonly ActionParamsClass_Permission s_params_Permission = new ActionParamsClass_Permission();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_Permission PermissionParams { get { return s_params_Permission; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_Permission
{
public readonly string id = "id";
public readonly string model = "model";
}
static readonly ViewsClass s_views = new ViewsClass();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ViewsClass Views { get { return s_views; } }
@@ -606,6 +623,19 @@ namespace Disco.Web.Areas.API.Controllers
return callInfo;
}
[NonAction]
partial void PermissionOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id, Disco.Web.Areas.API.Models.Shared.FlagPermissionModel model);
[NonAction]
public override System.Web.Mvc.ActionResult Permission(int id, Disco.Web.Areas.API.Models.Shared.FlagPermissionModel model)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Permission);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "model", model);
PermissionOverride(callInfo, id, model);
return callInfo;
}
}
}
@@ -308,6 +308,7 @@ namespace Disco.Web.Areas.API.Controllers
public class ActionParamsClass_SearchSubjects
{
public readonly string term = "term";
public readonly string includeAuthorizationRoles = "includeAuthorizationRoles";
}
static readonly ActionParamsClass_SearchGroupSubjects s_params_SearchGroupSubjects = new ActionParamsClass_SearchGroupSubjects();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
@@ -324,6 +325,7 @@ namespace Disco.Web.Areas.API.Controllers
public class ActionParamsClass_Subject
{
public readonly string Id = "Id";
public readonly string includeAuthorizationRoles = "includeAuthorizationRoles";
}
static readonly ActionParamsClass_SyncActiveDirectoryManagedGroup s_params_SyncActiveDirectoryManagedGroup = new ActionParamsClass_SyncActiveDirectoryManagedGroup();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
@@ -587,14 +589,15 @@ namespace Disco.Web.Areas.API.Controllers
}
[NonAction]
partial void SearchSubjectsOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string term);
partial void SearchSubjectsOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string term, bool includeAuthorizationRoles);
[NonAction]
public override System.Web.Mvc.ActionResult SearchSubjects(string term)
public override System.Web.Mvc.ActionResult SearchSubjects(string term, bool includeAuthorizationRoles)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.SearchSubjects);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "term", term);
SearchSubjectsOverride(callInfo, term);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "includeAuthorizationRoles", includeAuthorizationRoles);
SearchSubjectsOverride(callInfo, term, includeAuthorizationRoles);
return callInfo;
}
@@ -611,14 +614,15 @@ namespace Disco.Web.Areas.API.Controllers
}
[NonAction]
partial void SubjectOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string Id);
partial void SubjectOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string Id, bool includeAuthorizationRoles);
[NonAction]
public override System.Web.Mvc.ActionResult Subject(string Id)
public override System.Web.Mvc.ActionResult Subject(string Id, bool includeAuthorizationRoles)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Subject);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Id", Id);
SubjectOverride(callInfo, Id);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "includeAuthorizationRoles", includeAuthorizationRoles);
SubjectOverride(callInfo, Id, includeAuthorizationRoles);
return callInfo;
}
@@ -155,6 +155,12 @@ namespace Disco.Web.Areas.API.Controllers
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.SaveExport);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult Permission()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Permission);
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public UserFlagController Actions { get { return MVC.API.UserFlag; } }
@@ -187,6 +193,7 @@ namespace Disco.Web.Areas.API.Controllers
public readonly string Export = "Export";
public readonly string ExportRetrieve = "ExportRetrieve";
public readonly string SaveExport = "SaveExport";
public readonly string Permission = "Permission";
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
@@ -208,6 +215,7 @@ namespace Disco.Web.Areas.API.Controllers
public const string Export = "Export";
public const string ExportRetrieve = "ExportRetrieve";
public const string SaveExport = "SaveExport";
public const string Permission = "Permission";
}
@@ -367,6 +375,15 @@ namespace Disco.Web.Areas.API.Controllers
{
public readonly string model = "model";
}
static readonly ActionParamsClass_Permission s_params_Permission = new ActionParamsClass_Permission();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_Permission PermissionParams { get { return s_params_Permission; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_Permission
{
public readonly string id = "id";
public readonly string model = "model";
}
static readonly ViewsClass s_views = new ViewsClass();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ViewsClass Views { get { return s_views; } }
@@ -606,6 +623,19 @@ namespace Disco.Web.Areas.API.Controllers
return callInfo;
}
[NonAction]
partial void PermissionOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id, Disco.Web.Areas.API.Models.Shared.FlagPermissionModel model);
[NonAction]
public override System.Web.Mvc.ActionResult Permission(int id, Disco.Web.Areas.API.Models.Shared.FlagPermissionModel model)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Permission);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "model", model);
PermissionOverride(callInfo, id, model);
return callInfo;
}
}
}
@@ -1,15 +1,8 @@
@model Disco.Web.Models.Device.ShowModel
@using Disco.Services.Devices.DeviceFlags;
@{
Authorization.Require(Claims.Device.ShowFlagAssignments);
var hasRemove = Authorization.Has(Claims.Device.Actions.RemoveFlags);
var hasEdit = Authorization.Has(Claims.Device.Actions.EditFlags);
var hasDeviceFlagShow = Authorization.Has(Claims.Config.DeviceFlag.Show);
var activeAssignmentCount = Model.Device.DeviceFlagAssignments == null ? 0 : Model.Device.DeviceFlagAssignments.Count(a => !a.RemovedDate.HasValue);
var flagAssignments = Model.Device.DeviceFlagAssignments.Select(a => Tuple.Create(a, DeviceFlagService.GetDeviceFlag(a.DeviceFlagId))).ToList();
var flagAssignments = Model.Device.DeviceFlagAssignments.Select(a => Tuple.Create(a, DeviceFlagService.GetDeviceFlag(a.DeviceFlagId))).Where(a => a.Item2.permission.CanShow()).ToList();
var activeAssignmentCount = flagAssignments.Count(a => !a.Item1.RemovedDate.HasValue);
}
<div id="DeviceDetailTab-Flags" class="DevicePart">
@if (flagAssignments.Count > 0)
@@ -25,14 +18,14 @@
{
<tr data-deviceflagassignmentid="@fa.Item1.Id" data-flagassignmentaddeddate="@(fa.Item1.AddedDate.ToString("s"))" class="@(!fa.Item1.RemovedDate.HasValue ? "added" : "removed")">
<td class="name">
<i class="fa fa-@(fa.Item2.Icon) fa-fw fa-lg d-@(fa.Item2.IconColour)"></i>
@if (hasDeviceFlagShow)
<i class="fa fa-@(fa.Item2.flag.Icon) fa-fw fa-lg d-@(fa.Item2.flag.IconColour)"></i>
@if (Authorization.Has(Claims.Config.DeviceFlag.Show))
{
@Html.ActionLink(fa.Item2.Name, MVC.Config.DeviceFlag.Index(fa.Item2.Id))
@Html.ActionLink(fa.Item2.flag.Name, MVC.Config.DeviceFlag.Index(fa.Item2.flag.Id))
}
else
{
@fa.Item2.Name
@fa.Item2.flag.Name
}
</td>
<td class="added">
@@ -43,7 +36,7 @@
}
</td>
<td class="comments">
@if (hasEdit)
@if (fa.Item2.permission.CanEdit())
{
<div class="editable"><i class="fa fa-fw fa-edit" title="Edit Comments"></i></div>
}
@@ -77,6 +70,7 @@
<div id="Device_Show_Flags_Actions_Remove_Dialog" class="dialog" title="Remove this flag from the device?">
@using (Html.BeginForm(MVC.API.DeviceFlagAssignment.RemoveDevice()))
{
@Html.AntiForgeryToken()
<input id="Device_Show_Flags_Actions_Remove_Dialog_Id" type="hidden" name="id" value="" />
<p>
<i class="fa fa-exclamation-triangle fa-lg"></i>&nbsp;Are you sure?
@@ -86,6 +80,7 @@
<div id="Device_Show_Flags_Actions_EditComments_Dialog" class="dialog" title="Edit the Comments">
@using (Html.BeginForm(MVC.API.DeviceFlagAssignment.UpdateComments()))
{
@Html.AntiForgeryToken()
<input id="Device_Show_Flags_Actions_EditComments_Dialog_Id" type="hidden" name="id" value="" />
<input type="hidden" name="redirect" value="true" />
<h4>Comments:</h4>
@@ -52,15 +52,8 @@ namespace Disco.Web.Views.Device.DeviceParts
#line 3 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Authorization.Require(Claims.Device.ShowFlagAssignments);
var hasRemove = Authorization.Has(Claims.Device.Actions.RemoveFlags);
var hasEdit = Authorization.Has(Claims.Device.Actions.EditFlags);
var hasDeviceFlagShow = Authorization.Has(Claims.Config.DeviceFlag.Show);
var activeAssignmentCount = Model.Device.DeviceFlagAssignments == null ? 0 : Model.Device.DeviceFlagAssignments.Count(a => !a.RemovedDate.HasValue);
var flagAssignments = Model.Device.DeviceFlagAssignments.Select(a => Tuple.Create(a, DeviceFlagService.GetDeviceFlag(a.DeviceFlagId))).ToList();
var flagAssignments = Model.Device.DeviceFlagAssignments.Select(a => Tuple.Create(a, DeviceFlagService.GetDeviceFlag(a.DeviceFlagId))).Where(a => a.Item2.permission.CanShow()).ToList();
var activeAssignmentCount = flagAssignments.Count(a => !a.Item1.RemovedDate.HasValue);
#line default
@@ -74,13 +67,13 @@ WriteLiteral(" class=\"DevicePart\"");
WriteLiteral(">\r\n");
#line 15 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 8 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line default
#line hidden
#line 15 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 8 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
if (flagAssignments.Count > 0)
{
@@ -110,13 +103,13 @@ WriteLiteral(" class=\"removed\"");
WriteLiteral(">Removed</th>\r\n </tr>\r\n");
#line 24 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 17 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line default
#line hidden
#line 24 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 17 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
foreach (var fa in flagAssignments.OrderByDescending(a => a.Item1.AddedDate))
{
@@ -128,7 +121,7 @@ WriteLiteral(" <tr");
WriteLiteral(" data-deviceflagassignmentid=\"");
#line 26 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 19 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(fa.Item1.Id);
@@ -139,7 +132,7 @@ WriteLiteral("\"");
WriteLiteral(" data-flagassignmentaddeddate=\"");
#line 26 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 19 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(fa.Item1.AddedDate.ToString("s"));
@@ -147,14 +140,14 @@ WriteLiteral(" data-flagassignmentaddeddate=\"");
#line hidden
WriteLiteral("\"");
WriteAttribute("class", Tuple.Create(" class=\"", 1282), Tuple.Create("\"", 1345)
WriteAttribute("class", Tuple.Create(" class=\"", 967), Tuple.Create("\"", 1030)
#line 26 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 1290), Tuple.Create<System.Object, System.Int32>(!fa.Item1.RemovedDate.HasValue ? "added" : "removed"
#line 19 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 975), Tuple.Create<System.Object, System.Int32>(!fa.Item1.RemovedDate.HasValue ? "added" : "removed"
#line default
#line hidden
, 1290), false)
, 975), false)
);
WriteLiteral(">\r\n <td");
@@ -163,53 +156,53 @@ WriteLiteral(" class=\"name\"");
WriteLiteral(">\r\n <i");
WriteAttribute("class", Tuple.Create(" class=\"", 1414), Tuple.Create("\"", 1481)
, Tuple.Create(Tuple.Create("", 1422), Tuple.Create("fa", 1422), true)
, Tuple.Create(Tuple.Create(" ", 1424), Tuple.Create("fa-", 1425), true)
WriteAttribute("class", Tuple.Create(" class=\"", 1099), Tuple.Create("\"", 1176)
, Tuple.Create(Tuple.Create("", 1107), Tuple.Create("fa", 1107), true)
, Tuple.Create(Tuple.Create(" ", 1109), Tuple.Create("fa-", 1110), true)
#line 28 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 1428), Tuple.Create<System.Object, System.Int32>(fa.Item2.Icon
#line 21 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 1113), Tuple.Create<System.Object, System.Int32>(fa.Item2.flag.Icon
#line default
#line hidden
, 1428), false)
, Tuple.Create(Tuple.Create(" ", 1444), Tuple.Create("fa-fw", 1445), true)
, Tuple.Create(Tuple.Create(" ", 1450), Tuple.Create("fa-lg", 1451), true)
, Tuple.Create(Tuple.Create(" ", 1456), Tuple.Create("d-", 1457), true)
, 1113), false)
, Tuple.Create(Tuple.Create(" ", 1134), Tuple.Create("fa-fw", 1135), true)
, Tuple.Create(Tuple.Create(" ", 1140), Tuple.Create("fa-lg", 1141), true)
, Tuple.Create(Tuple.Create(" ", 1146), Tuple.Create("d-", 1147), true)
#line 28 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 1459), Tuple.Create<System.Object, System.Int32>(fa.Item2.IconColour
#line 21 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 1149), Tuple.Create<System.Object, System.Int32>(fa.Item2.flag.IconColour
#line default
#line hidden
, 1459), false)
, 1149), false)
);
WriteLiteral("></i>\r\n");
#line 29 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 22 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line default
#line hidden
#line 29 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
if (hasDeviceFlagShow)
#line 22 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
if (Authorization.Has(Claims.Config.DeviceFlag.Show))
{
#line default
#line hidden
#line 31 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(Html.ActionLink(fa.Item2.Name, MVC.Config.DeviceFlag.Index(fa.Item2.Id)));
#line 24 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(Html.ActionLink(fa.Item2.flag.Name, MVC.Config.DeviceFlag.Index(fa.Item2.flag.Id)));
#line default
#line hidden
#line 31 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 24 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
else
@@ -219,14 +212,14 @@ WriteLiteral("></i>\r\n");
#line default
#line hidden
#line 35 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(fa.Item2.Name);
#line 28 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(fa.Item2.flag.Name);
#line default
#line hidden
#line 35 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 28 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
@@ -242,7 +235,7 @@ WriteLiteral(">\r\n");
WriteLiteral(" ");
#line 39 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 32 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(CommonHelpers.FriendlyDateAndUser(fa.Item1.AddedDate, fa.Item1.AddedUser));
@@ -251,13 +244,13 @@ WriteLiteral(" ");
WriteLiteral("\r\n");
#line 40 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 33 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line default
#line hidden
#line 40 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 33 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
if (fa.Item1.OnAssignmentExpressionResult != null)
{
@@ -271,7 +264,7 @@ WriteLiteral(" class=\"expressionResult\"");
WriteLiteral(">");
#line 42 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 35 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(fa.Item1.OnAssignmentExpressionResult);
@@ -280,7 +273,7 @@ WriteLiteral(">");
WriteLiteral("</div>\r\n");
#line 43 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 36 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
@@ -293,14 +286,14 @@ WriteLiteral(" class=\"comments\"");
WriteLiteral(">\r\n");
#line 46 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 39 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line default
#line hidden
#line 46 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
if (hasEdit)
#line 39 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
if (fa.Item2.permission.CanEdit())
{
@@ -319,7 +312,7 @@ WriteLiteral(" title=\"Edit Comments\"");
WriteLiteral("></i></div>\r\n");
#line 49 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 42 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
@@ -328,7 +321,7 @@ WriteLiteral("></i></div>\r\n");
WriteLiteral(" ");
#line 50 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 43 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
if (fa.Item1.Comments == null)
{
@@ -342,7 +335,7 @@ WriteLiteral(" class=\"comments smallMessage\"");
WriteLiteral(">[no comments]</div>\r\n");
#line 53 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 46 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
else
{
@@ -357,7 +350,7 @@ WriteLiteral(" class=\"comments\"");
WriteLiteral(">");
#line 56 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 49 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(fa.Item1.Comments.ToHtmlComment());
@@ -372,7 +365,7 @@ WriteLiteral(" class=\"commentsRaw\"");
WriteLiteral(">");
#line 57 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 50 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(fa.Item1.Comments);
@@ -381,7 +374,7 @@ WriteLiteral(">");
WriteLiteral("</div>\r\n");
#line 58 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 51 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
@@ -389,27 +382,27 @@ WriteLiteral("</div>\r\n");
#line hidden
WriteLiteral(" </td>\r\n <td");
WriteAttribute("class", Tuple.Create(" class=\"", 3000), Tuple.Create("\"", 3063)
, Tuple.Create(Tuple.Create("", 3008), Tuple.Create("removed", 3008), true)
WriteAttribute("class", Tuple.Create(" class=\"", 2763), Tuple.Create("\"", 2826)
, Tuple.Create(Tuple.Create("", 2771), Tuple.Create("removed", 2771), true)
#line 60 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 3015), Tuple.Create<System.Object, System.Int32>(!fa.Item1.RemovedDate.HasValue ? " na" : null
#line 53 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 2778), Tuple.Create<System.Object, System.Int32>(!fa.Item1.RemovedDate.HasValue ? " na" : null
#line default
#line hidden
, 3015), false)
, 2778), false)
);
WriteLiteral(">\r\n");
#line 61 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 54 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line default
#line hidden
#line 61 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 54 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
if (fa.Item1.RemovedDate.HasValue)
{
@@ -417,14 +410,14 @@ WriteLiteral(">\r\n");
#line default
#line hidden
#line 63 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 56 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(CommonHelpers.FriendlyDateAndUser(fa.Item1.RemovedDate.Value, fa.Item1.RemovedUser));
#line default
#line hidden
#line 63 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 56 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
if (fa.Item1.OnUnassignmentExpressionResult != null)
{
@@ -439,7 +432,7 @@ WriteLiteral(" class=\"expressionResult\"");
WriteLiteral(">");
#line 66 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 59 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(fa.Item1.OnUnassignmentExpressionResult);
@@ -448,7 +441,7 @@ WriteLiteral(">");
WriteLiteral("</div>\r\n");
#line 67 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 60 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
}
else if (fa.Item1.CanRemove())
@@ -466,7 +459,7 @@ WriteLiteral(" class=\"button small remove\"");
WriteLiteral(">Remove</a>\r\n");
#line 72 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 65 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
@@ -475,7 +468,7 @@ WriteLiteral(">Remove</a>\r\n");
WriteLiteral(" </td>\r\n </tr>\r\n");
#line 75 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 68 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
@@ -494,17 +487,31 @@ WriteLiteral(" title=\"Remove this flag from the device?\"");
WriteLiteral(">\r\n");
#line 78 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 71 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line default
#line hidden
#line 78 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 71 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
using (Html.BeginForm(MVC.API.DeviceFlagAssignment.RemoveDevice()))
{
#line default
#line hidden
#line 73 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 73 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line default
#line hidden
WriteLiteral(" <input");
@@ -526,7 +533,7 @@ WriteLiteral(" class=\"fa fa-exclamation-triangle fa-lg\"");
WriteLiteral("></i>&nbsp;Are you sure?\r\n </p>\r\n");
#line 84 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 78 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
@@ -545,17 +552,31 @@ WriteLiteral(" title=\"Edit the Comments\"");
WriteLiteral(">\r\n");
#line 87 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 81 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line default
#line hidden
#line 87 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 81 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
using (Html.BeginForm(MVC.API.DeviceFlagAssignment.UpdateComments()))
{
#line default
#line hidden
#line 83 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 83 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line default
#line hidden
WriteLiteral(" <input");
@@ -593,7 +614,7 @@ WriteLiteral(" class=\"block\"");
WriteLiteral("></textarea>\r\n </p>\r\n");
#line 95 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 90 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
@@ -651,7 +672,7 @@ WriteLiteral(">\r\n $(function () {\r\n var deviceFlag
"eturn false;\r\n });\r\n });\r\n </script>\r\n");
#line 174 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 169 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
else
{
@@ -666,7 +687,7 @@ WriteLiteral(" class=\"none\"");
WriteLiteral(">This device has no associated flags</div>\r\n");
#line 178 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 173 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
}
@@ -676,7 +697,7 @@ WriteLiteral(" <script>\r\n $(\'#DeviceDetailTabItems\').append(\'<li>
"ilTab-Flags\">Flags [");
#line 180 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
#line 175 "..\..\Views\Device\DeviceParts\_Flags.cshtml"
Write(activeAssignmentCount);
@@ -239,17 +239,20 @@
<div id="Device_Show_User_EmailAddress" title="Email Address"><a href="mailto:@(Model.Device.AssignedUser.EmailAddress)" data-clipboard="@assignedUser.DisplayName &lt;@assignedUser.EmailAddress&gt;">@assignedUser.EmailAddress</a></div>
}
}
@if (Authorization.Has(Claims.User.ShowFlagAssignments))
@if (assignedUser.UserFlagAssignments.CanShowAny())
{
<div id="Device_Show_User_Flags">
@foreach (var flag in assignedUser.UserFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, UserFlagService.GetUserFlag(f.UserFlagId))))
{
<i class="flag fa fa-@(flag.Item2.Icon) fa-fw d-@(flag.Item2.IconColour)">
<span class="details">
<span class="name">@flag.Item2.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId)</span>
</span>
</i>
if (flag.Item2.permission.CanShow())
{
<i class="flag fa fa-@(flag.Item2.flag.Icon) fa-fw d-@(flag.Item2.flag.IconColour)">
<span class="details">
<span class="name">@flag.Item2.flag.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId)</span>
</span>
</i>
}
}
<script type="text/javascript">
$(function () {
@@ -765,12 +768,13 @@
});
</script>
}
@if (Model.Device.CanAddDeviceFlags() && Model.AvailableDeviceFlags != null && Model.AvailableDeviceFlags.Count > 0)
@if (Model.AvailableDeviceFlags != null && Model.AvailableDeviceFlags.Count > 0)
{
@Html.ActionLinkSmallButton("Add Flag", MVC.API.DeviceFlagAssignment.AddDevice(), "Device_Show_Details_Actions_AddFlag_Button")
<button id="Device_Show_Details_Actions_AddFlag_Button" type="button" class="button small">Add Flag</button>
<div id="Device_Show_Details_Actions_AddFlag_Dialog" class="dialog" title="Add Device Flag">
@using (Html.BeginForm(MVC.API.DeviceFlagAssignment.AddDevice()))
{
@Html.AntiForgeryToken()
<input id="Device_Show_Details_Actions_AddFlag_Dialog_Id" type="hidden" name="id" />
<input id="Device_Show_Details_Actions_AddFlag_Dialog_DeviceSerialNumber" type="hidden" name="DeviceSerialNumber" value="@Model.Device.SerialNumber" />
<div class="flagPicker">
@@ -794,7 +798,6 @@
$(function () {
const button = $('#Device_Show_Details_Actions_AddFlag_Button');
let buttonDialog = null;
const buttonLink = button.attr('href');
let flagPicker = null;
let flagAddId = null;
@@ -814,9 +817,7 @@
flagAddComments.focus().select();
}
button.attr('href', '#').click(function (e) {
e.preventDefault();
button.click(function (e) {
if (!buttonDialog) {
buttonDialog = $('#Device_Show_Details_Actions_AddFlag_Dialog');
buttonDialog.dialog({
@@ -831,10 +832,9 @@
},
"Add Flag": function () {
if (!!flagAddId.val()) {
const $this = $(this);
$this.dialog("disable");
$this.dialog("option", "buttons", null);
buttonDialog.find('form').submit();
buttonDialog
.dialog("option", "buttons", null)
.find('form').submit();
} else {
alert('Select a Device Flag');
}
@@ -868,7 +868,6 @@
$('#Device_Show_Details_Actions_AddFlag_Dialog_Filter').val('');
buttonDialog.dialog('open');
return false;
});
});
</script>
File diff suppressed because it is too large Load Diff
+11 -8
View File
@@ -19,17 +19,20 @@
});
</script>
</div>
@if (Authorization.Has(Claims.Device.ShowFlagAssignments))
@if (Model.Device.DeviceFlagAssignments.CanShowAny())
{
<div id="Device_Show_Flags">
@foreach (var flag in Model.Device.DeviceFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, DeviceFlagService.GetDeviceFlag(f.DeviceFlagId))))
{
<i class="flag fa fa-@(flag.Item2.Icon) fa-fw fa-lg d-@(flag.Item2.IconColour)">
<span class="details">
<span class="name">@flag.Item2.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUser)</span>
</span>
</i>
if (flag.Item2.permission.CanShow())
{
<i class="flag fa fa-@(flag.Item2.flag.Icon) fa-fw fa-lg d-@(flag.Item2.flag.IconColour)">
<span class="details">
<span class="name">@flag.Item2.flag.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUser)</span>
</span>
</i>
}
}
</div>
<script type="text/javascript">
@@ -116,7 +119,7 @@
{
@Html.Partial(MVC.Device.Views.DeviceParts._Resources, Model)
}
@if (Authorization.Has(Claims.Device.ShowFlagAssignments))
@if (Authorization.Has(Claims.Device.ShowFlagAssignments) || Model.Device.DeviceFlagAssignments.CanShowAny())
{
@Html.Partial(MVC.Device.Views.DeviceParts._Flags, Model)
}
+58 -55
View File
@@ -122,7 +122,7 @@ WriteLiteral(">\r\n $(function () {\r\n $(\'#Device_Sh
#line hidden
#line 22 "..\..\Views\Device\Show.cshtml"
if (Authorization.Has(Claims.Device.ShowFlagAssignments))
if (Model.Device.DeviceFlagAssignments.CanShowAny())
{
@@ -144,48 +144,50 @@ WriteLiteral(">\r\n");
#line 25 "..\..\Views\Device\Show.cshtml"
foreach (var flag in Model.Device.DeviceFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, DeviceFlagService.GetDeviceFlag(f.DeviceFlagId))))
{
if (flag.Item2.permission.CanShow())
{
#line default
#line hidden
WriteLiteral(" <i");
WriteLiteral(" <i");
WriteAttribute("class", Tuple.Create(" class=\"", 1178), Tuple.Create("\"", 1254)
, Tuple.Create(Tuple.Create("", 1186), Tuple.Create("flag", 1186), true)
, Tuple.Create(Tuple.Create(" ", 1190), Tuple.Create("fa", 1191), true)
, Tuple.Create(Tuple.Create(" ", 1193), Tuple.Create("fa-", 1194), true)
WriteAttribute("class", Tuple.Create(" class=\"", 1250), Tuple.Create("\"", 1336)
, Tuple.Create(Tuple.Create("", 1258), Tuple.Create("flag", 1258), true)
, Tuple.Create(Tuple.Create(" ", 1262), Tuple.Create("fa", 1263), true)
, Tuple.Create(Tuple.Create(" ", 1265), Tuple.Create("fa-", 1266), true)
#line 27 "..\..\Views\Device\Show.cshtml"
, Tuple.Create(Tuple.Create("", 1197), Tuple.Create<System.Object, System.Int32>(flag.Item2.Icon
#line 29 "..\..\Views\Device\Show.cshtml"
, Tuple.Create(Tuple.Create("", 1269), Tuple.Create<System.Object, System.Int32>(flag.Item2.flag.Icon
#line default
#line hidden
, 1197), false)
, Tuple.Create(Tuple.Create(" ", 1215), Tuple.Create("fa-fw", 1216), true)
, Tuple.Create(Tuple.Create(" ", 1221), Tuple.Create("fa-lg", 1222), true)
, Tuple.Create(Tuple.Create(" ", 1227), Tuple.Create("d-", 1228), true)
, 1269), false)
, Tuple.Create(Tuple.Create(" ", 1292), Tuple.Create("fa-fw", 1293), true)
, Tuple.Create(Tuple.Create(" ", 1298), Tuple.Create("fa-lg", 1299), true)
, Tuple.Create(Tuple.Create(" ", 1304), Tuple.Create("d-", 1305), true)
#line 27 "..\..\Views\Device\Show.cshtml"
, Tuple.Create(Tuple.Create("", 1230), Tuple.Create<System.Object, System.Int32>(flag.Item2.IconColour
#line 29 "..\..\Views\Device\Show.cshtml"
, Tuple.Create(Tuple.Create("", 1307), Tuple.Create<System.Object, System.Int32>(flag.Item2.flag.IconColour
#line default
#line hidden
, 1230), false)
, 1307), false)
);
WriteLiteral(">\r\n <span");
WriteLiteral(">\r\n <span");
WriteLiteral(" class=\"details\"");
WriteLiteral(">\r\n <span");
WriteLiteral(">\r\n <span");
WriteLiteral(" class=\"name\"");
WriteLiteral(">");
#line 29 "..\..\Views\Device\Show.cshtml"
Write(flag.Item2.Name);
#line 31 "..\..\Views\Device\Show.cshtml"
Write(flag.Item2.flag.Name);
#line default
@@ -193,9 +195,9 @@ WriteLiteral(">");
WriteLiteral("</span>");
#line 29 "..\..\Views\Device\Show.cshtml"
if (flag.Item1.Comments != null)
{
#line 31 "..\..\Views\Device\Show.cshtml"
if (flag.Item1.Comments != null)
{
#line default
#line hidden
@@ -206,8 +208,8 @@ WriteLiteral(" class=\"comments\"");
WriteLiteral(">");
#line 30 "..\..\Views\Device\Show.cshtml"
Write(flag.Item1.Comments.ToHtmlComment());
#line 32 "..\..\Views\Device\Show.cshtml"
Write(flag.Item1.Comments.ToHtmlComment());
#line default
@@ -215,8 +217,8 @@ WriteLiteral(">");
WriteLiteral("</span>");
#line 30 "..\..\Views\Device\Show.cshtml"
}
#line 32 "..\..\Views\Device\Show.cshtml"
}
#line default
#line hidden
@@ -227,16 +229,17 @@ WriteLiteral(" class=\"added\"");
WriteLiteral(">");
#line 30 "..\..\Views\Device\Show.cshtml"
Write(CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUser));
#line 32 "..\..\Views\Device\Show.cshtml"
Write(CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUser));
#line default
#line hidden
WriteLiteral("</span>\r\n </span>\r\n </i>\r\n");
WriteLiteral("</span>\r\n </span>\r\n </i>\r\n");
#line 33 "..\..\Views\Device\Show.cshtml"
#line 35 "..\..\Views\Device\Show.cshtml"
}
}
@@ -282,7 +285,7 @@ WriteLiteral(@">
");
#line 66 "..\..\Views\Device\Show.cshtml"
#line 69 "..\..\Views\Device\Show.cshtml"
}
@@ -291,7 +294,7 @@ WriteLiteral(@">
WriteLiteral(" ");
#line 67 "..\..\Views\Device\Show.cshtml"
#line 70 "..\..\Views\Device\Show.cshtml"
Write(Html.Partial(MVC.Device.Views.DeviceParts._Subject, Model));
@@ -332,13 +335,13 @@ WriteLiteral(" id=\"DeviceDetailTabItems\"");
WriteLiteral("></ul>\r\n");
#line 103 "..\..\Views\Device\Show.cshtml"
#line 106 "..\..\Views\Device\Show.cshtml"
#line default
#line hidden
#line 103 "..\..\Views\Device\Show.cshtml"
#line 106 "..\..\Views\Device\Show.cshtml"
if (Authorization.HasAny(Claims.Device.ShowComments, Claims.Device.ShowJobs))
{
@@ -346,14 +349,14 @@ WriteLiteral("></ul>\r\n");
#line default
#line hidden
#line 105 "..\..\Views\Device\Show.cshtml"
#line 108 "..\..\Views\Device\Show.cshtml"
Write(Html.Partial(MVC.Device.Views.DeviceParts._CommentsAndJobs, Model));
#line default
#line hidden
#line 105 "..\..\Views\Device\Show.cshtml"
#line 108 "..\..\Views\Device\Show.cshtml"
}
@@ -363,7 +366,7 @@ WriteLiteral("></ul>\r\n");
WriteLiteral(" ");
#line 107 "..\..\Views\Device\Show.cshtml"
#line 110 "..\..\Views\Device\Show.cshtml"
if (Authorization.Has(Claims.Device.ShowDetails))
{
@@ -371,14 +374,14 @@ WriteLiteral(" ");
#line default
#line hidden
#line 109 "..\..\Views\Device\Show.cshtml"
#line 112 "..\..\Views\Device\Show.cshtml"
Write(Html.Partial(MVC.Device.Views.DeviceParts._Details, Model));
#line default
#line hidden
#line 109 "..\..\Views\Device\Show.cshtml"
#line 112 "..\..\Views\Device\Show.cshtml"
}
@@ -388,7 +391,7 @@ WriteLiteral(" ");
WriteLiteral(" ");
#line 111 "..\..\Views\Device\Show.cshtml"
#line 114 "..\..\Views\Device\Show.cshtml"
if (Authorization.Has(Claims.Device.ShowAssignmentHistory))
{
@@ -396,14 +399,14 @@ WriteLiteral(" ");
#line default
#line hidden
#line 113 "..\..\Views\Device\Show.cshtml"
#line 116 "..\..\Views\Device\Show.cshtml"
Write(Html.Partial(MVC.Device.Views.DeviceParts._AssignmentHistory, Model));
#line default
#line hidden
#line 113 "..\..\Views\Device\Show.cshtml"
#line 116 "..\..\Views\Device\Show.cshtml"
}
@@ -413,7 +416,7 @@ WriteLiteral(" ");
WriteLiteral(" ");
#line 115 "..\..\Views\Device\Show.cshtml"
#line 118 "..\..\Views\Device\Show.cshtml"
if (Authorization.Has(Claims.Device.ShowAttachments))
{
@@ -421,14 +424,14 @@ WriteLiteral(" ");
#line default
#line hidden
#line 117 "..\..\Views\Device\Show.cshtml"
#line 120 "..\..\Views\Device\Show.cshtml"
Write(Html.Partial(MVC.Device.Views.DeviceParts._Resources, Model));
#line default
#line hidden
#line 117 "..\..\Views\Device\Show.cshtml"
#line 120 "..\..\Views\Device\Show.cshtml"
}
@@ -438,22 +441,22 @@ WriteLiteral(" ");
WriteLiteral(" ");
#line 119 "..\..\Views\Device\Show.cshtml"
if (Authorization.Has(Claims.Device.ShowFlagAssignments))
#line 122 "..\..\Views\Device\Show.cshtml"
if (Authorization.Has(Claims.Device.ShowFlagAssignments) || Model.Device.DeviceFlagAssignments.CanShowAny())
{
#line default
#line hidden
#line 121 "..\..\Views\Device\Show.cshtml"
#line 124 "..\..\Views\Device\Show.cshtml"
Write(Html.Partial(MVC.Device.Views.DeviceParts._Flags, Model));
#line default
#line hidden
#line 121 "..\..\Views\Device\Show.cshtml"
#line 124 "..\..\Views\Device\Show.cshtml"
}
@@ -463,7 +466,7 @@ WriteLiteral(" ");
WriteLiteral(" ");
#line 123 "..\..\Views\Device\Show.cshtml"
#line 126 "..\..\Views\Device\Show.cshtml"
if (Authorization.Has(Claims.Device.ShowCertificates))
{
@@ -471,14 +474,14 @@ WriteLiteral(" ");
#line default
#line hidden
#line 125 "..\..\Views\Device\Show.cshtml"
#line 128 "..\..\Views\Device\Show.cshtml"
Write(Html.Partial(MVC.Device.Views.DeviceParts._Certificates, Model));
#line default
#line hidden
#line 125 "..\..\Views\Device\Show.cshtml"
#line 128 "..\..\Views\Device\Show.cshtml"
}
@@ -488,13 +491,13 @@ WriteLiteral(" ");
WriteLiteral(" </div>\r\n");
#line 128 "..\..\Views\Device\Show.cshtml"
#line 131 "..\..\Views\Device\Show.cshtml"
#line default
#line hidden
#line 128 "..\..\Views\Device\Show.cshtml"
#line 131 "..\..\Views\Device\Show.cshtml"
if (requiresLive)
{
@@ -550,7 +553,7 @@ WriteLiteral(" <script>\r\n $(function () {\r\n
" </script>\r\n");
#line 197 "..\..\Views\Device\Show.cshtml"
#line 200 "..\..\Views\Device\Show.cshtml"
}
+41 -41
View File
@@ -32,22 +32,22 @@
{@Html.ActionLink(item.Id, MVC.Device.Show(item.Id))}
else
{@item.Id}
@if (Authorization.Has(Claims.Device.ShowFlagAssignments))
@if (item.DeviceFlagAssignments.CanShowAny())
{
@if (item.DeviceFlagAssignments != null && item.DeviceFlagAssignments.Count > 0)
{
<div class="flags">
@foreach (var flag in item.DeviceFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, DeviceFlagService.GetDeviceFlag(f.DeviceFlagId))))
<div class="flags">
@foreach (var flag in item.DeviceFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, DeviceFlagService.GetDeviceFlag(f.DeviceFlagId))))
{
@if (flag.Item2.permission.CanShow())
{
<i class="flag fa fa-@(flag.Item2.Icon) fa-fw d-@(flag.Item2.IconColour)">
<i class="flag fa fa-@(flag.Item2.flag.Icon) fa-fw d-@(flag.Item2.flag.IconColour)">
<span class="details">
<span class="name">@flag.Item2.Name</span>@if (flag.Item1.Comments != null)
<span class="name">@flag.Item2.flag.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId)</span>
</span>
</i>
}
</div>
}
}
</div>
}
</td>
<td>
@@ -117,43 +117,43 @@
</tbody>
</table>
<script type="text/javascript">
$(function () {
var userTable = $('table.deviceTable');
$(function () {
var userTable = $('table.deviceTable');
userTable.each(function () {
var $this = $(this);
userTable.each(function () {
var $this = $(this);
if (!$this.data('deviceTable_Flags')) {
$this.tooltip({
items: 'i.flag',
content: function () {
var $this = $(this);
return $this.children('.details').html();
},
tooltipClass: 'FlagAssignment_Tooltip',
position: {
my: "right top",
at: "right bottom",
collision: "flipfit flip"
},
hade: {
effect: ''
},
close: function (e, ui) {
ui.tooltip.hover(
function () {
$(this).stop(true).fadeTo(100, 1);
if (!$this.data('deviceTable_Flags')) {
$this.tooltip({
items: 'i.flag',
content: function () {
var $this = $(this);
return $this.children('.details').html();
},
function () {
$(this).fadeOut(100, function () { $(this).remove(); });
});
tooltipClass: 'FlagAssignment_Tooltip',
position: {
my: "right top",
at: "right bottom",
collision: "flipfit flip"
},
hade: {
effect: ''
},
close: function (e, ui) {
ui.tooltip.hover(
function () {
$(this).stop(true).fadeTo(100, 1);
},
function () {
$(this).fadeOut(100, function () { $(this).remove(); });
});
}
});
$this.data('deviceTable_Flags', true)
}
});
$this.data('deviceTable_Flags', true)
}
});
});
});
</script>
}
else
@@ -175,35 +175,35 @@ WriteLiteral(" ");
#line 35 "..\..\Views\Device\_DeviceTable.cshtml"
if (Authorization.Has(Claims.Device.ShowFlagAssignments))
if (item.DeviceFlagAssignments.CanShowAny())
{
#line default
#line hidden
#line 37 "..\..\Views\Device\_DeviceTable.cshtml"
if (item.DeviceFlagAssignments != null && item.DeviceFlagAssignments.Count > 0)
{
#line default
#line hidden
WriteLiteral(" <div");
WriteLiteral(" <div");
WriteLiteral(" class=\"flags\"");
WriteLiteral(">\r\n");
#line 40 "..\..\Views\Device\_DeviceTable.cshtml"
#line 38 "..\..\Views\Device\_DeviceTable.cshtml"
#line default
#line hidden
#line 38 "..\..\Views\Device\_DeviceTable.cshtml"
foreach (var flag in item.DeviceFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, DeviceFlagService.GetDeviceFlag(f.DeviceFlagId))))
{
#line default
#line hidden
#line 40 "..\..\Views\Device\_DeviceTable.cshtml"
foreach (var flag in item.DeviceFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, DeviceFlagService.GetDeviceFlag(f.DeviceFlagId))))
if (flag.Item2.permission.CanShow())
{
@@ -211,26 +211,26 @@ WriteLiteral(">\r\n");
#line hidden
WriteLiteral(" <i");
WriteAttribute("class", Tuple.Create(" class=\"", 1953), Tuple.Create("\"", 2023)
, Tuple.Create(Tuple.Create("", 1961), Tuple.Create("flag", 1961), true)
, Tuple.Create(Tuple.Create(" ", 1965), Tuple.Create("fa", 1966), true)
, Tuple.Create(Tuple.Create(" ", 1968), Tuple.Create("fa-", 1969), true)
WriteAttribute("class", Tuple.Create(" class=\"", 1901), Tuple.Create("\"", 1981)
, Tuple.Create(Tuple.Create("", 1909), Tuple.Create("flag", 1909), true)
, Tuple.Create(Tuple.Create(" ", 1913), Tuple.Create("fa", 1914), true)
, Tuple.Create(Tuple.Create(" ", 1916), Tuple.Create("fa-", 1917), true)
#line 42 "..\..\Views\Device\_DeviceTable.cshtml"
, Tuple.Create(Tuple.Create("", 1972), Tuple.Create<System.Object, System.Int32>(flag.Item2.Icon
, Tuple.Create(Tuple.Create("", 1920), Tuple.Create<System.Object, System.Int32>(flag.Item2.flag.Icon
#line default
#line hidden
, 1972), false)
, Tuple.Create(Tuple.Create(" ", 1990), Tuple.Create("fa-fw", 1991), true)
, Tuple.Create(Tuple.Create(" ", 1996), Tuple.Create("d-", 1997), true)
, 1920), false)
, Tuple.Create(Tuple.Create(" ", 1943), Tuple.Create("fa-fw", 1944), true)
, Tuple.Create(Tuple.Create(" ", 1949), Tuple.Create("d-", 1950), true)
#line 42 "..\..\Views\Device\_DeviceTable.cshtml"
, Tuple.Create(Tuple.Create("", 1999), Tuple.Create<System.Object, System.Int32>(flag.Item2.IconColour
, Tuple.Create(Tuple.Create("", 1952), Tuple.Create<System.Object, System.Int32>(flag.Item2.flag.IconColour
#line default
#line hidden
, 1999), false)
, 1952), false)
);
WriteLiteral(">\r\n <span");
@@ -245,7 +245,7 @@ WriteLiteral(">");
#line 44 "..\..\Views\Device\_DeviceTable.cshtml"
Write(flag.Item2.Name);
Write(flag.Item2.flag.Name);
#line default
@@ -254,7 +254,7 @@ WriteLiteral("</span>");
#line 44 "..\..\Views\Device\_DeviceTable.cshtml"
if (flag.Item1.Comments != null)
if (flag.Item1.Comments != null)
{
#line default
@@ -302,17 +302,18 @@ WriteLiteral("</span>\r\n </span>
#line default
#line hidden
WriteLiteral("\r\n </div>\r\n");
#line 48 "..\..\Views\Device\_DeviceTable.cshtml"
}
#line 50 "..\..\Views\Device\_DeviceTable.cshtml"
}
#line default
#line hidden
WriteLiteral(" </div>\r\n");
#line 50 "..\..\Views\Device\_DeviceTable.cshtml"
#line 51 "..\..\Views\Device\_DeviceTable.cshtml"
}
@@ -627,46 +628,27 @@ WriteLiteral(" <script");
WriteLiteral(" type=\"text/javascript\"");
WriteLiteral(@">
$(function () {
var userTable = $('table.deviceTable');
userTable.each(function () {
var $this = $(this);
if (!$this.data('deviceTable_Flags')) {
$this.tooltip({
items: 'i.flag',
content: function () {
var $this = $(this);
return $this.children('.details').html();
},
tooltipClass: 'FlagAssignment_Tooltip',
position: {
my: ""right top"",
at: ""right bottom"",
collision: ""flipfit flip""
},
hade: {
effect: ''
},
close: function (e, ui) {
ui.tooltip.hover(
function () {
$(this).stop(true).fadeTo(100, 1);
},
function () {
$(this).fadeOut(100, function () { $(this).remove(); });
});
}
});
$this.data('deviceTable_Flags', true)
}
});
});
</script>
");
WriteLiteral(">\r\n $(function () {\r\n var userTable = $(\'table.deviceTa" +
"ble\');\r\n\r\n userTable.each(function () {\r\n var " +
"$this = $(this);\r\n\r\n if (!$this.data(\'deviceTable_Flags\')) {\r" +
"\n $this.tooltip({\r\n items: \'i." +
"flag\',\r\n content: function () {\r\n " +
" var $this = $(this);\r\n return $this.c" +
"hildren(\'.details\').html();\r\n },\r\n " +
" tooltipClass: \'FlagAssignment_Tooltip\',\r\n po" +
"sition: {\r\n my: \"right top\",\r\n " +
" at: \"right bottom\",\r\n collision: \"fl" +
"ipfit flip\"\r\n },\r\n hade: {" +
"\r\n effect: \'\'\r\n },\r\n " +
" close: function (e, ui) {\r\n " +
" ui.tooltip.hover(\r\n function () {\r\n " +
" $(this).stop(true).fadeTo(100, 1);\r\n " +
" },\r\n function () {" +
"\r\n $(this).fadeOut(100, function () { $(t" +
"his).remove(); });\r\n });\r\n " +
" }\r\n });\r\n\r\n $this.data(\'d" +
"eviceTable_Flags\', true)\r\n }\r\n });\r\n " +
" });\r\n </script>\r\n");
#line 158 "..\..\Views\Device\_DeviceTable.cshtml"
+20 -16
View File
@@ -256,19 +256,20 @@
</div>
}
}
@if (Authorization.Has(Claims.Device.ShowFlagAssignments) &&
Model.Job.Device.DeviceFlagAssignments != null &&
Model.Job.Device.DeviceFlagAssignments.Any(a => !a.RemovedDate.HasValue))
@if (Model.Job.Device.DeviceFlagAssignments.CanShowAny())
{
<div id="Job_Show_Device_Flags">
@foreach (var flag in Model.Job.Device.DeviceFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, DeviceFlagService.GetDeviceFlag(f.DeviceFlagId))))
{
<i class="flag fa fa-@(flag.Item2.Icon) fa-fw d-@(flag.Item2.IconColour)">
<span class="details">
<span class="name">@flag.Item2.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId)</span>
</span>
</i>
if (flag.Item2.permission.CanShow())
{
<i class="flag fa fa-@(flag.Item2.flag.Icon) fa-fw d-@(flag.Item2.flag.IconColour)">
<span class="details">
<span class="name">@flag.Item2.flag.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId)</span>
</span>
</i>
}
}
<script type="text/javascript">
$(function () {
@@ -506,17 +507,20 @@
if (!string.IsNullOrWhiteSpace(Model.Job.User.EmailAddress))
{<div id="Job_Show_User_EmailAddress" title="Email Address">Email: <a href="mailto:@(Model.Job.User.EmailAddress)" data-clipboard="@Model.Job.User.DisplayName &lt;@Model.Job.User.EmailAddress&gt;">@Model.Job.User.EmailAddress</a></div>}
}
@if (Authorization.Has(Claims.User.ShowFlagAssignments))
@if (Model.Job.User.UserFlagAssignments.CanShowAny())
{
<div id="Job_Show_User_Flags">
@foreach (var flag in Model.Job.User.UserFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, UserFlagService.GetUserFlag(f.UserFlagId))))
{
<i class="flag fa fa-@(flag.Item2.Icon) fa-fw d-@(flag.Item2.IconColour)">
<span class="details">
<span class="name">@flag.Item2.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId)</span>
</span>
</i>
if (flag.Item2.permission.CanShow())
{
<i class="flag fa fa-@(flag.Item2.flag.Icon) fa-fw d-@(flag.Item2.flag.IconColour)">
<span class="details">
<span class="name">@flag.Item2.flag.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId)</span>
</span>
</i>
}
}
<script type="text/javascript">
$(function () {
File diff suppressed because it is too large Load Diff
+11 -8
View File
@@ -13,17 +13,20 @@
}
}
<div id="User_Show" data-userid="@Model.User.UserId">
@if (Authorization.Has(Claims.User.ShowFlagAssignments))
@if (Model.User.UserFlagAssignments.CanShowAny())
{
<div id="User_Show_Flags">
@foreach (var flag in Model.User.UserFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, UserFlagService.GetUserFlag(f.UserFlagId))))
{
<i class="flag fa fa-@(flag.Item2.Icon) fa-fw fa-lg d-@(flag.Item2.IconColour)">
<span class="details">
<span class="name">@flag.Item2.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUser)</span>
</span>
</i>
if (flag.Item2.permission.CanShow())
{
<i class="flag fa fa-@(flag.Item2.flag.Icon) fa-fw fa-lg d-@(flag.Item2.flag.IconColour)">
<span class="details">
<span class="name">@flag.Item2.flag.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUser)</span>
</span>
</i>
}
}
</div>
<script type="text/javascript">
@@ -106,7 +109,7 @@
{
@Html.Partial(MVC.User.Views.UserParts._Resources, Model)
}
@if (Authorization.Has(Claims.User.ShowFlagAssignments))
@if (Authorization.Has(Claims.User.ShowFlagAssignments) || Model.User.UserFlagAssignments.CanShowAny())
{
@Html.Partial(MVC.User.Views.UserParts._Flags, Model)
}
+55 -52
View File
@@ -91,7 +91,7 @@ WriteLiteral(">\r\n");
#line hidden
#line 16 "..\..\Views\User\Show.cshtml"
if (Authorization.Has(Claims.User.ShowFlagAssignments))
if (Model.User.UserFlagAssignments.CanShowAny())
{
@@ -113,48 +113,50 @@ WriteLiteral(">\r\n");
#line 19 "..\..\Views\User\Show.cshtml"
foreach (var flag in Model.User.UserFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, UserFlagService.GetUserFlag(f.UserFlagId))))
{
if (flag.Item2.permission.CanShow())
{
#line default
#line hidden
WriteLiteral(" <i");
WriteLiteral(" <i");
WriteAttribute("class", Tuple.Create(" class=\"", 867), Tuple.Create("\"", 943)
, Tuple.Create(Tuple.Create("", 875), Tuple.Create("flag", 875), true)
, Tuple.Create(Tuple.Create(" ", 879), Tuple.Create("fa", 880), true)
, Tuple.Create(Tuple.Create(" ", 882), Tuple.Create("fa-", 883), true)
WriteAttribute("class", Tuple.Create(" class=\"", 937), Tuple.Create("\"", 1023)
, Tuple.Create(Tuple.Create("", 945), Tuple.Create("flag", 945), true)
, Tuple.Create(Tuple.Create(" ", 949), Tuple.Create("fa", 950), true)
, Tuple.Create(Tuple.Create(" ", 952), Tuple.Create("fa-", 953), true)
#line 21 "..\..\Views\User\Show.cshtml"
, Tuple.Create(Tuple.Create("", 886), Tuple.Create<System.Object, System.Int32>(flag.Item2.Icon
#line 23 "..\..\Views\User\Show.cshtml"
, Tuple.Create(Tuple.Create("", 956), Tuple.Create<System.Object, System.Int32>(flag.Item2.flag.Icon
#line default
#line hidden
, 886), false)
, Tuple.Create(Tuple.Create(" ", 904), Tuple.Create("fa-fw", 905), true)
, Tuple.Create(Tuple.Create(" ", 910), Tuple.Create("fa-lg", 911), true)
, Tuple.Create(Tuple.Create(" ", 916), Tuple.Create("d-", 917), true)
, 956), false)
, Tuple.Create(Tuple.Create(" ", 979), Tuple.Create("fa-fw", 980), true)
, Tuple.Create(Tuple.Create(" ", 985), Tuple.Create("fa-lg", 986), true)
, Tuple.Create(Tuple.Create(" ", 991), Tuple.Create("d-", 992), true)
#line 21 "..\..\Views\User\Show.cshtml"
, Tuple.Create(Tuple.Create("", 919), Tuple.Create<System.Object, System.Int32>(flag.Item2.IconColour
#line 23 "..\..\Views\User\Show.cshtml"
, Tuple.Create(Tuple.Create("", 994), Tuple.Create<System.Object, System.Int32>(flag.Item2.flag.IconColour
#line default
#line hidden
, 919), false)
, 994), false)
);
WriteLiteral(">\r\n <span");
WriteLiteral(">\r\n <span");
WriteLiteral(" class=\"details\"");
WriteLiteral(">\r\n <span");
WriteLiteral(">\r\n <span");
WriteLiteral(" class=\"name\"");
WriteLiteral(">");
#line 23 "..\..\Views\User\Show.cshtml"
Write(flag.Item2.Name);
#line 25 "..\..\Views\User\Show.cshtml"
Write(flag.Item2.flag.Name);
#line default
@@ -162,9 +164,9 @@ WriteLiteral(">");
WriteLiteral("</span>");
#line 23 "..\..\Views\User\Show.cshtml"
if (flag.Item1.Comments != null)
{
#line 25 "..\..\Views\User\Show.cshtml"
if (flag.Item1.Comments != null)
{
#line default
#line hidden
@@ -175,8 +177,8 @@ WriteLiteral(" class=\"comments\"");
WriteLiteral(">");
#line 24 "..\..\Views\User\Show.cshtml"
Write(flag.Item1.Comments.ToHtmlComment());
#line 26 "..\..\Views\User\Show.cshtml"
Write(flag.Item1.Comments.ToHtmlComment());
#line default
@@ -184,8 +186,8 @@ WriteLiteral(">");
WriteLiteral("</span>");
#line 24 "..\..\Views\User\Show.cshtml"
}
#line 26 "..\..\Views\User\Show.cshtml"
}
#line default
#line hidden
@@ -196,16 +198,17 @@ WriteLiteral(" class=\"added\"");
WriteLiteral(">");
#line 24 "..\..\Views\User\Show.cshtml"
Write(CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUser));
#line 26 "..\..\Views\User\Show.cshtml"
Write(CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUser));
#line default
#line hidden
WriteLiteral("</span>\r\n </span>\r\n </i>\r\n");
WriteLiteral("</span>\r\n </span>\r\n </i>\r\n");
#line 27 "..\..\Views\User\Show.cshtml"
#line 29 "..\..\Views\User\Show.cshtml"
}
}
@@ -251,7 +254,7 @@ WriteLiteral(@">
");
#line 60 "..\..\Views\User\Show.cshtml"
#line 63 "..\..\Views\User\Show.cshtml"
}
@@ -260,7 +263,7 @@ WriteLiteral(@">
WriteLiteral(" ");
#line 61 "..\..\Views\User\Show.cshtml"
#line 64 "..\..\Views\User\Show.cshtml"
Write(Html.Partial(MVC.User.Views.UserParts._Subject, Model));
@@ -300,13 +303,13 @@ WriteLiteral(" id=\"UserDetailTabItems\"");
WriteLiteral("></ul>\r\n");
#line 97 "..\..\Views\User\Show.cshtml"
#line 100 "..\..\Views\User\Show.cshtml"
#line default
#line hidden
#line 97 "..\..\Views\User\Show.cshtml"
#line 100 "..\..\Views\User\Show.cshtml"
if (Authorization.HasAny(Claims.User.ShowComments, Claims.User.ShowJobs))
{
@@ -314,14 +317,14 @@ WriteLiteral("></ul>\r\n");
#line default
#line hidden
#line 99 "..\..\Views\User\Show.cshtml"
#line 102 "..\..\Views\User\Show.cshtml"
Write(Html.Partial(MVC.User.Views.UserParts._CommentsAndJobs, Model));
#line default
#line hidden
#line 99 "..\..\Views\User\Show.cshtml"
#line 102 "..\..\Views\User\Show.cshtml"
}
@@ -331,7 +334,7 @@ WriteLiteral("></ul>\r\n");
WriteLiteral(" ");
#line 101 "..\..\Views\User\Show.cshtml"
#line 104 "..\..\Views\User\Show.cshtml"
if (Authorization.Has(Claims.User.ShowAssignmentHistory))
{
@@ -339,14 +342,14 @@ WriteLiteral(" ");
#line default
#line hidden
#line 103 "..\..\Views\User\Show.cshtml"
#line 106 "..\..\Views\User\Show.cshtml"
Write(Html.Partial(MVC.User.Views.UserParts._AssignmentHistory, Model));
#line default
#line hidden
#line 103 "..\..\Views\User\Show.cshtml"
#line 106 "..\..\Views\User\Show.cshtml"
}
@@ -356,7 +359,7 @@ WriteLiteral(" ");
WriteLiteral(" ");
#line 105 "..\..\Views\User\Show.cshtml"
#line 108 "..\..\Views\User\Show.cshtml"
if (Authorization.Has(Claims.User.ShowAttachments))
{
@@ -364,14 +367,14 @@ WriteLiteral(" ");
#line default
#line hidden
#line 107 "..\..\Views\User\Show.cshtml"
#line 110 "..\..\Views\User\Show.cshtml"
Write(Html.Partial(MVC.User.Views.UserParts._Resources, Model));
#line default
#line hidden
#line 107 "..\..\Views\User\Show.cshtml"
#line 110 "..\..\Views\User\Show.cshtml"
}
@@ -381,22 +384,22 @@ WriteLiteral(" ");
WriteLiteral(" ");
#line 109 "..\..\Views\User\Show.cshtml"
if (Authorization.Has(Claims.User.ShowFlagAssignments))
#line 112 "..\..\Views\User\Show.cshtml"
if (Authorization.Has(Claims.User.ShowFlagAssignments) || Model.User.UserFlagAssignments.CanShowAny())
{
#line default
#line hidden
#line 111 "..\..\Views\User\Show.cshtml"
#line 114 "..\..\Views\User\Show.cshtml"
Write(Html.Partial(MVC.User.Views.UserParts._Flags, Model));
#line default
#line hidden
#line 111 "..\..\Views\User\Show.cshtml"
#line 114 "..\..\Views\User\Show.cshtml"
}
@@ -406,7 +409,7 @@ WriteLiteral(" ");
WriteLiteral(" ");
#line 113 "..\..\Views\User\Show.cshtml"
#line 116 "..\..\Views\User\Show.cshtml"
if (Authorization.Has(Claims.User.ShowAuthorization))
{
@@ -414,14 +417,14 @@ WriteLiteral(" ");
#line default
#line hidden
#line 115 "..\..\Views\User\Show.cshtml"
#line 118 "..\..\Views\User\Show.cshtml"
Write(Html.Partial(MVC.User.Views.UserParts._Authorization, Model));
#line default
#line hidden
#line 115 "..\..\Views\User\Show.cshtml"
#line 118 "..\..\Views\User\Show.cshtml"
}
@@ -431,13 +434,13 @@ WriteLiteral(" ");
WriteLiteral(" </div>\r\n");
#line 118 "..\..\Views\User\Show.cshtml"
#line 121 "..\..\Views\User\Show.cshtml"
#line default
#line hidden
#line 118 "..\..\Views\User\Show.cshtml"
#line 121 "..\..\Views\User\Show.cshtml"
if (requiresLive)
{
@@ -492,7 +495,7 @@ WriteLiteral(" <script>\r\n $(function () {\r\n
" });\r\n });\r\n </script>\r\n");
#line 187 "..\..\Views\User\Show.cshtml"
#line 190 "..\..\Views\User\Show.cshtml"
}
+9 -14
View File
@@ -1,15 +1,8 @@
@model Disco.Web.Models.User.ShowModel
@using Disco.Services.Users.UserFlags;
@{
Authorization.Require(Claims.User.ShowFlagAssignments);
var hasRemove = Authorization.Has(Claims.User.Actions.RemoveFlags);
var hasEdit = Authorization.Has(Claims.User.Actions.EditFlags);
var hasUserFlagShow = Authorization.Has(Claims.Config.UserFlag.Show);
var activeAssignmentCount = Model.User.UserFlagAssignments == null ? 0 : Model.User.UserFlagAssignments.Count(a => !a.RemovedDate.HasValue);
var flagAssignments = Model.User.UserFlagAssignments.Select(a => Tuple.Create(a, UserFlagService.GetUserFlag(a.UserFlagId))).ToList();
var flagAssignments = Model.User.UserFlagAssignments.Select(a => Tuple.Create(a, UserFlagService.GetUserFlag(a.UserFlagId))).Where(g => g.Item2.permission.CanShow()).ToList();
var activeAssignmentCount = flagAssignments.Count(a => !a.Item1.RemovedDate.HasValue);
}
<div id="UserDetailTab-Flags" class="UserPart">
@if (flagAssignments.Count > 0)
@@ -25,14 +18,14 @@
{
<tr data-userflagassignmentid="@fa.Item1.Id" data-flagassignmentaddeddate="@(fa.Item1.AddedDate.ToString("s"))" class="@(!fa.Item1.RemovedDate.HasValue ? "added" : "removed")">
<td class="name">
<i class="fa fa-@(fa.Item2.Icon) fa-fw fa-lg d-@(fa.Item2.IconColour)"></i>
@if (hasUserFlagShow)
<i class="fa fa-@(fa.Item2.flag.Icon) fa-fw fa-lg d-@(fa.Item2.flag.IconColour)"></i>
@if (Authorization.Has(Claims.Config.UserFlag.Show))
{
@Html.ActionLink(fa.Item2.Name, MVC.Config.UserFlag.Index(fa.Item2.Id))
@Html.ActionLink(fa.Item2.flag.Name, MVC.Config.UserFlag.Index(fa.Item2.flag.Id))
}
else
{
@fa.Item2.Name
@fa.Item2.flag.Name
}
</td>
<td class="added">
@@ -43,7 +36,7 @@
}
</td>
<td class="comments">
@if (hasEdit)
@if (fa.Item2.permission.CanEdit())
{
<div class="editable"><i class="fa fa-fw fa-edit" title="Edit Comments"></i></div>
}
@@ -77,6 +70,7 @@
<div id="User_Show_Flags_Actions_Remove_Dialog" class="dialog" title="Remove this flag from the user?">
@using (Html.BeginForm(MVC.API.UserFlagAssignment.RemoveUser()))
{
@Html.AntiForgeryToken()
<input id="User_Show_Flags_Actions_Remove_Dialog_Id" type="hidden" name="id" value="" />
<p>
<i class="fa fa-exclamation-triangle fa-lg"></i>&nbsp;Are you sure?
@@ -86,6 +80,7 @@
<div id="User_Show_Flags_Actions_EditComments_Dialog" class="dialog" title="Edit the Comments">
@using (Html.BeginForm(MVC.API.UserFlagAssignment.UpdateComments()))
{
@Html.AntiForgeryToken()
<input id="User_Show_Flags_Actions_EditComments_Dialog_Id" type="hidden" name="id" value="" />
<input type="hidden" name="redirect" value="true" />
<h4>Comments:</h4>
@@ -52,15 +52,8 @@ namespace Disco.Web.Views.User.UserParts
#line 3 "..\..\Views\User\UserParts\_Flags.cshtml"
Authorization.Require(Claims.User.ShowFlagAssignments);
var hasRemove = Authorization.Has(Claims.User.Actions.RemoveFlags);
var hasEdit = Authorization.Has(Claims.User.Actions.EditFlags);
var hasUserFlagShow = Authorization.Has(Claims.Config.UserFlag.Show);
var activeAssignmentCount = Model.User.UserFlagAssignments == null ? 0 : Model.User.UserFlagAssignments.Count(a => !a.RemovedDate.HasValue);
var flagAssignments = Model.User.UserFlagAssignments.Select(a => Tuple.Create(a, UserFlagService.GetUserFlag(a.UserFlagId))).ToList();
var flagAssignments = Model.User.UserFlagAssignments.Select(a => Tuple.Create(a, UserFlagService.GetUserFlag(a.UserFlagId))).Where(g => g.Item2.permission.CanShow()).ToList();
var activeAssignmentCount = flagAssignments.Count(a => !a.Item1.RemovedDate.HasValue);
#line default
@@ -74,13 +67,13 @@ WriteLiteral(" class=\"UserPart\"");
WriteLiteral(">\r\n");
#line 15 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 8 "..\..\Views\User\UserParts\_Flags.cshtml"
#line default
#line hidden
#line 15 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 8 "..\..\Views\User\UserParts\_Flags.cshtml"
if (flagAssignments.Count > 0)
{
@@ -110,13 +103,13 @@ WriteLiteral(" class=\"removed\"");
WriteLiteral(">Removed</th>\r\n </tr>\r\n");
#line 24 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 17 "..\..\Views\User\UserParts\_Flags.cshtml"
#line default
#line hidden
#line 24 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 17 "..\..\Views\User\UserParts\_Flags.cshtml"
foreach (var fa in flagAssignments.OrderByDescending(a => a.Item1.AddedDate))
{
@@ -128,7 +121,7 @@ WriteLiteral(" <tr");
WriteLiteral(" data-userflagassignmentid=\"");
#line 26 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 19 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(fa.Item1.Id);
@@ -139,7 +132,7 @@ WriteLiteral("\"");
WriteLiteral(" data-flagassignmentaddeddate=\"");
#line 26 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 19 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(fa.Item1.AddedDate.ToString("s"));
@@ -147,14 +140,14 @@ WriteLiteral(" data-flagassignmentaddeddate=\"");
#line hidden
WriteLiteral("\"");
WriteAttribute("class", Tuple.Create(" class=\"", 1240), Tuple.Create("\"", 1303)
WriteAttribute("class", Tuple.Create(" class=\"", 943), Tuple.Create("\"", 1006)
#line 26 "..\..\Views\User\UserParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 1248), Tuple.Create<System.Object, System.Int32>(!fa.Item1.RemovedDate.HasValue ? "added" : "removed"
#line 19 "..\..\Views\User\UserParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 951), Tuple.Create<System.Object, System.Int32>(!fa.Item1.RemovedDate.HasValue ? "added" : "removed"
#line default
#line hidden
, 1248), false)
, 951), false)
);
WriteLiteral(">\r\n <td");
@@ -163,53 +156,53 @@ WriteLiteral(" class=\"name\"");
WriteLiteral(">\r\n <i");
WriteAttribute("class", Tuple.Create(" class=\"", 1372), Tuple.Create("\"", 1439)
, Tuple.Create(Tuple.Create("", 1380), Tuple.Create("fa", 1380), true)
, Tuple.Create(Tuple.Create(" ", 1382), Tuple.Create("fa-", 1383), true)
WriteAttribute("class", Tuple.Create(" class=\"", 1075), Tuple.Create("\"", 1152)
, Tuple.Create(Tuple.Create("", 1083), Tuple.Create("fa", 1083), true)
, Tuple.Create(Tuple.Create(" ", 1085), Tuple.Create("fa-", 1086), true)
#line 28 "..\..\Views\User\UserParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 1386), Tuple.Create<System.Object, System.Int32>(fa.Item2.Icon
#line 21 "..\..\Views\User\UserParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 1089), Tuple.Create<System.Object, System.Int32>(fa.Item2.flag.Icon
#line default
#line hidden
, 1386), false)
, Tuple.Create(Tuple.Create(" ", 1402), Tuple.Create("fa-fw", 1403), true)
, Tuple.Create(Tuple.Create(" ", 1408), Tuple.Create("fa-lg", 1409), true)
, Tuple.Create(Tuple.Create(" ", 1414), Tuple.Create("d-", 1415), true)
, 1089), false)
, Tuple.Create(Tuple.Create(" ", 1110), Tuple.Create("fa-fw", 1111), true)
, Tuple.Create(Tuple.Create(" ", 1116), Tuple.Create("fa-lg", 1117), true)
, Tuple.Create(Tuple.Create(" ", 1122), Tuple.Create("d-", 1123), true)
#line 28 "..\..\Views\User\UserParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 1417), Tuple.Create<System.Object, System.Int32>(fa.Item2.IconColour
#line 21 "..\..\Views\User\UserParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 1125), Tuple.Create<System.Object, System.Int32>(fa.Item2.flag.IconColour
#line default
#line hidden
, 1417), false)
, 1125), false)
);
WriteLiteral("></i>\r\n");
#line 29 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 22 "..\..\Views\User\UserParts\_Flags.cshtml"
#line default
#line hidden
#line 29 "..\..\Views\User\UserParts\_Flags.cshtml"
if (hasUserFlagShow)
#line 22 "..\..\Views\User\UserParts\_Flags.cshtml"
if (Authorization.Has(Claims.Config.UserFlag.Show))
{
#line default
#line hidden
#line 31 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(Html.ActionLink(fa.Item2.Name, MVC.Config.UserFlag.Index(fa.Item2.Id)));
#line 24 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(Html.ActionLink(fa.Item2.flag.Name, MVC.Config.UserFlag.Index(fa.Item2.flag.Id)));
#line default
#line hidden
#line 31 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 24 "..\..\Views\User\UserParts\_Flags.cshtml"
}
else
@@ -219,14 +212,14 @@ WriteLiteral("></i>\r\n");
#line default
#line hidden
#line 35 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(fa.Item2.Name);
#line 28 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(fa.Item2.flag.Name);
#line default
#line hidden
#line 35 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 28 "..\..\Views\User\UserParts\_Flags.cshtml"
}
@@ -242,7 +235,7 @@ WriteLiteral(">\r\n");
WriteLiteral(" ");
#line 39 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 32 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(CommonHelpers.FriendlyDateAndUser(fa.Item1.AddedDate, fa.Item1.AddedUser));
@@ -251,13 +244,13 @@ WriteLiteral(" ");
WriteLiteral("\r\n");
#line 40 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 33 "..\..\Views\User\UserParts\_Flags.cshtml"
#line default
#line hidden
#line 40 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 33 "..\..\Views\User\UserParts\_Flags.cshtml"
if (fa.Item1.OnAssignmentExpressionResult != null)
{
@@ -271,7 +264,7 @@ WriteLiteral(" class=\"expressionResult\"");
WriteLiteral(">");
#line 42 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 35 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(fa.Item1.OnAssignmentExpressionResult);
@@ -280,7 +273,7 @@ WriteLiteral(">");
WriteLiteral("</div>\r\n");
#line 43 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 36 "..\..\Views\User\UserParts\_Flags.cshtml"
}
@@ -293,14 +286,14 @@ WriteLiteral(" class=\"comments\"");
WriteLiteral(">\r\n");
#line 46 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 39 "..\..\Views\User\UserParts\_Flags.cshtml"
#line default
#line hidden
#line 46 "..\..\Views\User\UserParts\_Flags.cshtml"
if (hasEdit)
#line 39 "..\..\Views\User\UserParts\_Flags.cshtml"
if (fa.Item2.permission.CanEdit())
{
@@ -319,7 +312,7 @@ WriteLiteral(" title=\"Edit Comments\"");
WriteLiteral("></i></div>\r\n");
#line 49 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 42 "..\..\Views\User\UserParts\_Flags.cshtml"
}
@@ -328,7 +321,7 @@ WriteLiteral("></i></div>\r\n");
WriteLiteral(" ");
#line 50 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 43 "..\..\Views\User\UserParts\_Flags.cshtml"
if (fa.Item1.Comments == null)
{
@@ -342,7 +335,7 @@ WriteLiteral(" class=\"comments smallMessage\"");
WriteLiteral(">[no comments]</div>\r\n");
#line 53 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 46 "..\..\Views\User\UserParts\_Flags.cshtml"
}
else
{
@@ -357,7 +350,7 @@ WriteLiteral(" class=\"comments\"");
WriteLiteral(">");
#line 56 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 49 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(fa.Item1.Comments.ToHtmlComment());
@@ -372,7 +365,7 @@ WriteLiteral(" class=\"commentsRaw\"");
WriteLiteral(">");
#line 57 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 50 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(fa.Item1.Comments);
@@ -381,7 +374,7 @@ WriteLiteral(">");
WriteLiteral("</div>\r\n");
#line 58 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 51 "..\..\Views\User\UserParts\_Flags.cshtml"
}
@@ -389,27 +382,27 @@ WriteLiteral("</div>\r\n");
#line hidden
WriteLiteral(" </td>\r\n <td");
WriteAttribute("class", Tuple.Create(" class=\"", 2954), Tuple.Create("\"", 3017)
, Tuple.Create(Tuple.Create("", 2962), Tuple.Create("removed", 2962), true)
WriteAttribute("class", Tuple.Create(" class=\"", 2735), Tuple.Create("\"", 2798)
, Tuple.Create(Tuple.Create("", 2743), Tuple.Create("removed", 2743), true)
#line 60 "..\..\Views\User\UserParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 2969), Tuple.Create<System.Object, System.Int32>(!fa.Item1.RemovedDate.HasValue ? " na" : null
#line 53 "..\..\Views\User\UserParts\_Flags.cshtml"
, Tuple.Create(Tuple.Create("", 2750), Tuple.Create<System.Object, System.Int32>(!fa.Item1.RemovedDate.HasValue ? " na" : null
#line default
#line hidden
, 2969), false)
, 2750), false)
);
WriteLiteral(">\r\n");
#line 61 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 54 "..\..\Views\User\UserParts\_Flags.cshtml"
#line default
#line hidden
#line 61 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 54 "..\..\Views\User\UserParts\_Flags.cshtml"
if (fa.Item1.RemovedDate.HasValue)
{
@@ -417,14 +410,14 @@ WriteLiteral(">\r\n");
#line default
#line hidden
#line 63 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 56 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(CommonHelpers.FriendlyDateAndUser(fa.Item1.RemovedDate.Value, fa.Item1.RemovedUser));
#line default
#line hidden
#line 63 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 56 "..\..\Views\User\UserParts\_Flags.cshtml"
if (fa.Item1.OnUnassignmentExpressionResult != null)
{
@@ -439,7 +432,7 @@ WriteLiteral(" class=\"expressionResult\"");
WriteLiteral(">");
#line 66 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 59 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(fa.Item1.OnUnassignmentExpressionResult);
@@ -448,7 +441,7 @@ WriteLiteral(">");
WriteLiteral("</div>\r\n");
#line 67 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 60 "..\..\Views\User\UserParts\_Flags.cshtml"
}
}
else if (fa.Item1.CanRemove())
@@ -466,7 +459,7 @@ WriteLiteral(" class=\"button small remove\"");
WriteLiteral(">Remove</a>\r\n");
#line 72 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 65 "..\..\Views\User\UserParts\_Flags.cshtml"
}
@@ -475,7 +468,7 @@ WriteLiteral(">Remove</a>\r\n");
WriteLiteral(" </td>\r\n </tr>\r\n");
#line 75 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 68 "..\..\Views\User\UserParts\_Flags.cshtml"
}
@@ -494,17 +487,31 @@ WriteLiteral(" title=\"Remove this flag from the user?\"");
WriteLiteral(">\r\n");
#line 78 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 71 "..\..\Views\User\UserParts\_Flags.cshtml"
#line default
#line hidden
#line 78 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 71 "..\..\Views\User\UserParts\_Flags.cshtml"
using (Html.BeginForm(MVC.API.UserFlagAssignment.RemoveUser()))
{
#line default
#line hidden
#line 73 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 73 "..\..\Views\User\UserParts\_Flags.cshtml"
#line default
#line hidden
WriteLiteral(" <input");
@@ -526,7 +533,7 @@ WriteLiteral(" class=\"fa fa-exclamation-triangle fa-lg\"");
WriteLiteral("></i>&nbsp;Are you sure?\r\n </p>\r\n");
#line 84 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 78 "..\..\Views\User\UserParts\_Flags.cshtml"
}
@@ -545,17 +552,31 @@ WriteLiteral(" title=\"Edit the Comments\"");
WriteLiteral(">\r\n");
#line 87 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 81 "..\..\Views\User\UserParts\_Flags.cshtml"
#line default
#line hidden
#line 87 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 81 "..\..\Views\User\UserParts\_Flags.cshtml"
using (Html.BeginForm(MVC.API.UserFlagAssignment.UpdateComments()))
{
#line default
#line hidden
#line 83 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 83 "..\..\Views\User\UserParts\_Flags.cshtml"
#line default
#line hidden
WriteLiteral(" <input");
@@ -593,7 +614,7 @@ WriteLiteral(" class=\"block\"");
WriteLiteral("></textarea>\r\n </p>\r\n");
#line 95 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 90 "..\..\Views\User\UserParts\_Flags.cshtml"
}
@@ -651,7 +672,7 @@ WriteLiteral(">\r\n $(function () {\r\n var userFlags
";\r\n });\r\n </script>\r\n");
#line 174 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 169 "..\..\Views\User\UserParts\_Flags.cshtml"
}
else
{
@@ -666,7 +687,7 @@ WriteLiteral(" class=\"none\"");
WriteLiteral(">This user has no associated flags</div>\r\n");
#line 178 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 173 "..\..\Views\User\UserParts\_Flags.cshtml"
}
@@ -676,7 +697,7 @@ WriteLiteral(" <script>\r\n $(\'#UserDetailTabItems\').append(\'<li><a
"b-Flags\">Flags [");
#line 180 "..\..\Views\User\UserParts\_Flags.cshtml"
#line 175 "..\..\Views\User\UserParts\_Flags.cshtml"
Write(activeAssignmentCount);
+17 -16
View File
@@ -236,12 +236,13 @@
</script>
}
}
@if (Model.User.CanAddUserFlags() && Model.AvailableUserFlags != null && Model.AvailableUserFlags.Count > 0)
@if (Model.AvailableUserFlags != null && Model.AvailableUserFlags.Count > 0)
{
@Html.ActionLinkSmallButton("Add Flag", MVC.API.UserFlagAssignment.AddUser(), "User_Show_Details_Actions_AddFlag_Button")
<button id="User_Show_Details_Actions_AddFlag_Button" type="button" class="button small">Add Flag</button>
<div id="User_Show_Details_Actions_AddFlag_Dialog" class="dialog" title="Add User Flag">
@using (Html.BeginForm(MVC.API.UserFlagAssignment.AddUser()))
{
@Html.AntiForgeryToken()
<input id="User_Show_Details_Actions_AddFlag_Dialog_Id" type="hidden" name="id" />
<input id="User_Show_Details_Actions_AddFlag_Dialog_UserId" type="hidden" name="UserId" value="@Model.User.UserId" />
<div class="flagPicker">
@@ -265,7 +266,6 @@
$(function () {
const button = $('#User_Show_Details_Actions_AddFlag_Button');
let buttonDialog = null;
const buttonLink = button.attr('href');
let flagPicker = null;
let flagAddId = null;
@@ -285,7 +285,7 @@
flagAddComments.focus().select();
}
button.attr('href', '#').click(function (e) {
button.click(function (e) {
e.preventDefault();
if (!buttonDialog) {
@@ -302,10 +302,9 @@
},
"Add Flag": function () {
if (!!flagAddId.val()) {
const $this = $(this);
$this.dialog("disable");
$this.dialog("option", "buttons", null);
buttonDialog.find('form').submit();
buttonDialog
.dialog("option", "buttons", null)
.find('form').submit();
} else {
alert('Select a User Flag');
}
@@ -437,20 +436,22 @@
<span class="User_Show_AssignedDevices_CurrentAssignment_Assigned">@CommonHelpers.FriendlyDate(assignment.AssignedDate)</span>
</td>
</tr>
@if (Authorization.Has(Claims.Device.ShowFlagAssignments) &&
assignment.Device.DeviceFlagAssignments.Any(a => a.RemovedDate.HasValue))
@if (assignment.Device.DeviceFlagAssignments.CanShowAny())
{
<tr>
<td colspan="2">
<div class="User_Show_Assigned_Devices_CurrentAssignment_Flags">
@foreach (var flag in assignment.Device.DeviceFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, DeviceFlagService.GetDeviceFlag(f.DeviceFlagId))))
{
<i class="flag fa fa-@(flag.Item2.Icon) fa-fw d-@(flag.Item2.IconColour)">
<span class="details">
<span class="name">@flag.Item2.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId)</span>
</span>
</i>
if (flag.Item2.permission.CanShow())
{
<i class="flag fa fa-@(flag.Item2.flag.Icon) fa-fw d-@(flag.Item2.flag.IconColour)">
<span class="details">
<span class="name">@flag.Item2.flag.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId)</span>
</span>
</i>
}
}
<script type="text/javascript">
$(function () {
@@ -893,26 +893,22 @@ WriteLiteral(" ");
#line 239 "..\..\Views\User\UserParts\_Subject.cshtml"
if (Model.User.CanAddUserFlags() && Model.AvailableUserFlags != null && Model.AvailableUserFlags.Count > 0)
if (Model.AvailableUserFlags != null && Model.AvailableUserFlags.Count > 0)
{
#line default
#line hidden
WriteLiteral(" <button");
#line 241 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(Html.ActionLinkSmallButton("Add Flag", MVC.API.UserFlagAssignment.AddUser(), "User_Show_Details_Actions_AddFlag_Button"));
WriteLiteral(" id=\"User_Show_Details_Actions_AddFlag_Button\"");
WriteLiteral(" type=\"button\"");
#line default
#line hidden
WriteLiteral(" class=\"button small\"");
#line 241 "..\..\Views\User\UserParts\_Subject.cshtml"
WriteLiteral(">Add Flag</button>\r\n");
#line default
#line hidden
WriteLiteral(" <div");
WriteLiteral(" id=\"User_Show_Details_Actions_AddFlag_Dialog\"");
@@ -935,6 +931,20 @@ WriteLiteral(">\r\n");
{
#line default
#line hidden
#line 245 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 245 "..\..\Views\User\UserParts\_Subject.cshtml"
#line default
#line hidden
WriteLiteral(" <input");
@@ -955,14 +965,14 @@ WriteLiteral(" type=\"hidden\"");
WriteLiteral(" name=\"UserId\"");
WriteAttribute("value", Tuple.Create(" value=\"", 16008), Tuple.Create("\"", 16034)
WriteAttribute("value", Tuple.Create(" value=\"", 16023), Tuple.Create("\"", 16049)
#line 246 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 16016), Tuple.Create<System.Object, System.Int32>(Model.User.UserId
#line 247 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 16031), Tuple.Create<System.Object, System.Int32>(Model.User.UserId
#line default
#line hidden
, 16016), false)
, 16031), false)
);
WriteLiteral(" />\r\n");
@@ -984,13 +994,13 @@ WriteLiteral(" autocomplete=\"off\"");
WriteLiteral(" />\r\n");
#line 249 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 250 "..\..\Views\User\UserParts\_Subject.cshtml"
#line default
#line hidden
#line 249 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 250 "..\..\Views\User\UserParts\_Subject.cshtml"
foreach (var userFlag in Model.AvailableUserFlags.OrderBy(jq => jq.Name))
{
@@ -1004,7 +1014,7 @@ WriteLiteral(" class=\"flag\"");
WriteLiteral(" data-userflagid=\"");
#line 251 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 252 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(userFlag.Id);
@@ -1015,7 +1025,7 @@ WriteLiteral("\"");
WriteLiteral(" data-userflagname=\"");
#line 251 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 252 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(userFlag.Name);
@@ -1025,32 +1035,32 @@ WriteLiteral("\"");
WriteLiteral(">\r\n <i");
WriteAttribute("class", Tuple.Create(" class=\"", 16599), Tuple.Create("\"", 16666)
, Tuple.Create(Tuple.Create("", 16607), Tuple.Create("fa", 16607), true)
, Tuple.Create(Tuple.Create(" ", 16609), Tuple.Create("fa-", 16610), true)
WriteAttribute("class", Tuple.Create(" class=\"", 16614), Tuple.Create("\"", 16681)
, Tuple.Create(Tuple.Create("", 16622), Tuple.Create("fa", 16622), true)
, Tuple.Create(Tuple.Create(" ", 16624), Tuple.Create("fa-", 16625), true)
#line 252 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 16613), Tuple.Create<System.Object, System.Int32>(userFlag.Icon
#line 253 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 16628), Tuple.Create<System.Object, System.Int32>(userFlag.Icon
#line default
#line hidden
, 16613), false)
, Tuple.Create(Tuple.Create(" ", 16629), Tuple.Create("fa-fw", 16630), true)
, Tuple.Create(Tuple.Create(" ", 16635), Tuple.Create("fa-lg", 16636), true)
, Tuple.Create(Tuple.Create(" ", 16641), Tuple.Create("d-", 16642), true)
, 16628), false)
, Tuple.Create(Tuple.Create(" ", 16644), Tuple.Create("fa-fw", 16645), true)
, Tuple.Create(Tuple.Create(" ", 16650), Tuple.Create("fa-lg", 16651), true)
, Tuple.Create(Tuple.Create(" ", 16656), Tuple.Create("d-", 16657), true)
#line 252 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 16644), Tuple.Create<System.Object, System.Int32>(userFlag.IconColour
#line 253 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 16659), Tuple.Create<System.Object, System.Int32>(userFlag.IconColour
#line default
#line hidden
, 16644), false)
, 16659), false)
);
WriteLiteral("></i>");
#line 252 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 253 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(userFlag.Name);
@@ -1059,7 +1069,7 @@ WriteLiteral("></i>");
WriteLiteral("\r\n </div>\r\n");
#line 254 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 255 "..\..\Views\User\UserParts\_Subject.cshtml"
}
@@ -1083,7 +1093,7 @@ WriteLiteral("></textarea>\r\n </div>\r\n
" </div>\r\n");
#line 262 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 263 "..\..\Views\User\UserParts\_Subject.cshtml"
}
@@ -1097,72 +1107,69 @@ WriteLiteral(" type=\"text/javascript\"");
WriteLiteral(">\r\n $(function () {\r\n " +
" const button = $(\'#User_Show_Details_Actions_AddFlag_Button\');\r\n " +
" let buttonDialog = null;\r\n " +
" const buttonLink = button.attr(\'href\');\r\n\r\n " +
" let flagPicker = null;\r\n let flagAddI" +
"d = null;\r\n let flagAddComments = null;\r\n " +
" let details = null;\r\n\r\n " +
" function flagSelected() {\r\n co" +
"nst flag = $(this);\r\n\r\n flagPicker.childr" +
"en().removeClass(\'selected\');\r\n flag.addC" +
"lass(\'selected\');\r\n\r\n flagAddId.val(flag." +
"attr(\'data-userflagid\'));\r\n\r\n details.sho" +
"w();\r\n\r\n flagAddComments.focus().select()" +
";\r\n }\r\n\r\n " +
"button.attr(\'href\', \'#\').click(function (e) {\r\n " +
" e.preventDefault();\r\n\r\n if (!butto" +
"nDialog) {\r\n buttonDialog = $(\'#User_" +
"Show_Details_Actions_AddFlag_Dialog\');\r\n " +
" buttonDialog.dialog({\r\n width" +
": 600,\r\n height: 410,\r\n " +
" resizable: false,\r\n " +
" modal: true,\r\n " +
" autoOpen: false,\r\n buttons" +
": {\r\n Cancel: function () {\r\n" +
" $(this).dialog(\"close\");" +
"\r\n },\r\n " +
" \"Add Flag\": function () {\r\n " +
" if (!!flagAddId.val()) {\r\n " +
" const $this = $(this);\r\n " +
" $this.dialog(\"disable\");\r\n " +
" $this.dialog(\"option\", \"buttons" +
"\", null);\r\n buttonDia" +
"log.find(\'form\').submit();\r\n " +
" } else {\r\n alert(" +
"\'Select a User Flag\');\r\n " +
"}\r\n }\r\n " +
" }\r\n });\r\n\r\n" +
" flagAddId = $(\'#User_Show_Details_Ac" +
"tions_AddFlag_Dialog_Id\');\r\n flagAddC" +
"omments = buttonDialog.find(\'#User_Show_Details_Actions_AddFlag_Dialog_Comments\'" +
");\r\n flagPicker = buttonDialog.find(\'" +
".flagPicker\');\r\n details = buttonDial" +
"og.find(\'.details\');\r\n\r\n $(\'#User_Sho" +
"w_Details_Actions_AddFlag_Dialog_Filter\').on(\'keyup\', function (e) {\r\n " +
" const filter = $(e.currentTarget).val().to" +
"LowerCase();\r\n if (filter) {\r\n " +
" flagPicker.children(\'div.flag\')" +
".each(function () {\r\n con" +
"st $this = $(this);\r\n if " +
"($this.attr(\'data-userflagname\').toLowerCase().indexOf(filter) >= 0) {\r\n " +
" $this.css(\'display\', \'block\'" +
");\r\n } else {\r\n " +
" $this.css(\'display\', \'none\');\r" +
"\n }\r\n " +
" });\r\n " +
" } else {\r\n flagPicker.ch" +
"ildren(\'div.flag\').each(function () { $(this).css(\'display\', \'block\'); });\r\n " +
" }\r\n " +
" });\r\n\r\n flagPicker.on(\'cli" +
"ck\', \'div.flag\', flagSelected);\r\n }\r\n\r\n " +
" $(\'#User_Show_Details_Actions_AddFlag_Dial" +
"og_Filter\').val(\'\');\r\n buttonDialog.dialo" +
"g(\'open\');\r\n return false;\r\n " +
" });\r\n });\r\n " +
" </script>\r\n");
" let buttonDialog = null;\r\n\r\n " +
" let flagPicker = null;\r\n let flagA" +
"ddId = null;\r\n let flagAddComments = null;\r\n " +
" let details = null;\r\n\r\n " +
" function flagSelected() {\r\n " +
" const flag = $(this);\r\n\r\n flagPicker.chi" +
"ldren().removeClass(\'selected\');\r\n flag.a" +
"ddClass(\'selected\');\r\n\r\n flagAddId.val(fl" +
"ag.attr(\'data-userflagid\'));\r\n\r\n details." +
"show();\r\n\r\n flagAddComments.focus().selec" +
"t();\r\n }\r\n\r\n " +
" button.click(function (e) {\r\n e.preven" +
"tDefault();\r\n\r\n if (!buttonDialog) {\r\n " +
" buttonDialog = $(\'#User_Show_Details_Ac" +
"tions_AddFlag_Dialog\');\r\n buttonDialo" +
"g.dialog({\r\n width: 600,\r\n " +
" height: 410,\r\n " +
" resizable: false,\r\n " +
" modal: true,\r\n autoOpen" +
": false,\r\n buttons: {\r\n " +
" Cancel: function () {\r\n " +
" $(this).dialog(\"close\");\r\n " +
" },\r\n " +
" \"Add Flag\": function () {\r\n " +
" if (!!flagAddId.val()) {\r\n " +
" buttonDialog\r\n " +
" .dialog(\"option\", \"buttons\", null)\r\n " +
" .find(\'form\').submit();\r\n " +
" } else {\r\n " +
" alert(\'Select a User Flag\');\r\n " +
" }\r\n " +
" }\r\n }\r\n " +
" });\r\n\r\n " +
" flagAddId = $(\'#User_Show_Details_Actions_AddFlag_Dialog_Id\');\r\n " +
" flagAddComments = buttonDialog.find(\'#User_Show_D" +
"etails_Actions_AddFlag_Dialog_Comments\');\r\n " +
" flagPicker = buttonDialog.find(\'.flagPicker\');\r\n " +
" details = buttonDialog.find(\'.details\');\r\n\r\n " +
" $(\'#User_Show_Details_Actions_AddFlag_Dialog_Filter\')" +
".on(\'keyup\', function (e) {\r\n con" +
"st filter = $(e.currentTarget).val().toLowerCase();\r\n " +
" if (filter) {\r\n " +
" flagPicker.children(\'div.flag\').each(function () {\r\n " +
" const $this = $(this);\r\n " +
" if ($this.attr(\'data-userflagname\').toLowerC" +
"ase().indexOf(filter) >= 0) {\r\n " +
" $this.css(\'display\', \'block\');\r\n " +
" } else {\r\n " +
" $this.css(\'display\', \'none\');\r\n " +
" }\r\n });\r\n " +
" } else {\r\n " +
" flagPicker.children(\'div.flag\').each(function () { $(t" +
"his).css(\'display\', \'block\'); });\r\n " +
" }\r\n });\r\n\r\n " +
" flagPicker.on(\'click\', \'div.flag\', flagSelected);\r\n " +
" }\r\n\r\n $(\'" +
"#User_Show_Details_Actions_AddFlag_Dialog_Filter\').val(\'\');\r\n " +
" buttonDialog.dialog(\'open\');\r\n " +
" return false;\r\n });\r\n " +
" });\r\n </script>\r\n");
#line 346 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 345 "..\..\Views\User\UserParts\_Subject.cshtml"
}
@@ -1171,13 +1178,13 @@ WriteLiteral(">\r\n $(function () {\r\n
WriteLiteral(" </div>\r\n </div>\r\n </td>\r\n");
#line 350 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 349 "..\..\Views\User\UserParts\_Subject.cshtml"
#line default
#line hidden
#line 350 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 349 "..\..\Views\User\UserParts\_Subject.cshtml"
if (Authorization.Has(Claims.User.ShowAssignments))
{
@@ -1195,13 +1202,13 @@ WriteLiteral(" id=\"User_Show_AssignedDevices_Active\"");
WriteLiteral(">\r\n <h3>Current Device Assignments</h3>\r\n");
#line 356 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 355 "..\..\Views\User\UserParts\_Subject.cshtml"
#line default
#line hidden
#line 356 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 355 "..\..\Views\User\UserParts\_Subject.cshtml"
if (currentDeviceAssignments.Count > 0)
{
foreach (var assignment in currentDeviceAssignments)
@@ -1217,7 +1224,7 @@ WriteLiteral(" class=\"User_Show_AssignedDevices_CurrentAssignment clearfix\"");
WriteLiteral(" data-deviceserialnumber=\"");
#line 360 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 359 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(assignment.DeviceSerialNumber);
@@ -1228,13 +1235,13 @@ WriteLiteral("\"");
WriteLiteral(">\r\n");
#line 361 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 360 "..\..\Views\User\UserParts\_Subject.cshtml"
#line default
#line hidden
#line 361 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 360 "..\..\Views\User\UserParts\_Subject.cshtml"
if (Authorization.Has(Claims.Device.Show))
{
@@ -1243,14 +1250,14 @@ WriteLiteral(">\r\n");
#line hidden
WriteLiteral(" <a");
WriteAttribute("href", Tuple.Create(" href=\"", 23450), Tuple.Create("\"", 23517)
WriteAttribute("href", Tuple.Create(" href=\"", 23264), Tuple.Create("\"", 23331)
#line 363 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 23457), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.Device.Show(assignment.Device.SerialNumber))
#line 362 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 23271), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.Device.Show(assignment.Device.SerialNumber))
#line default
#line hidden
, 23457), false)
, 23271), false)
);
WriteLiteral(">\r\n <img");
@@ -1259,20 +1266,20 @@ WriteLiteral(" class=\"User_Show_AssignedDevices_CurrentAssignment_Image\"");
WriteLiteral(" alt=\"Model Image\"");
WriteAttribute("src", Tuple.Create(" src=\"", 23649), Tuple.Create("\"", 23770)
WriteAttribute("src", Tuple.Create(" src=\"", 23463), Tuple.Create("\"", 23584)
#line 364 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 23655), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.DeviceModel.Image(assignment.Device.DeviceModel.Id, assignment.Device.DeviceModel.ImageHash()))
#line 363 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 23469), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.DeviceModel.Image(assignment.Device.DeviceModel.Id, assignment.Device.DeviceModel.ImageHash()))
#line default
#line hidden
, 23655), false)
, 23469), false)
);
WriteLiteral(" />\r\n </a>\r\n");
#line 366 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 365 "..\..\Views\User\UserParts\_Subject.cshtml"
}
else
{
@@ -1286,20 +1293,20 @@ WriteLiteral(" class=\"User_Show_AssignedDevices_CurrentAssignment_Image\"");
WriteLiteral(" alt=\"Model Image\"");
WriteAttribute("src", Tuple.Create(" src=\"", 24082), Tuple.Create("\"", 24203)
WriteAttribute("src", Tuple.Create(" src=\"", 23896), Tuple.Create("\"", 24017)
#line 369 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 24088), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.DeviceModel.Image(assignment.Device.DeviceModel.Id, assignment.Device.DeviceModel.ImageHash()))
#line 368 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 23902), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.DeviceModel.Image(assignment.Device.DeviceModel.Id, assignment.Device.DeviceModel.ImageHash()))
#line default
#line hidden
, 24088), false)
, 23902), false)
);
WriteLiteral(" />\r\n");
#line 370 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 369 "..\..\Views\User\UserParts\_Subject.cshtml"
}
@@ -1327,13 +1334,13 @@ WriteLiteral(" class=\"User_Show_AssignedDevices_CurrentAssignment_SerialNumber\
WriteLiteral(" data-clipboard>\r\n");
#line 380 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 379 "..\..\Views\User\UserParts\_Subject.cshtml"
#line default
#line hidden
#line 380 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 379 "..\..\Views\User\UserParts\_Subject.cshtml"
if (Authorization.Has(Claims.Device.Show))
{
@@ -1341,14 +1348,14 @@ WriteLiteral(" data-clipboard>\r\n");
#line default
#line hidden
#line 382 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 381 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(Html.ActionLink(assignment.Device.SerialNumber, MVC.Device.Show(assignment.Device.SerialNumber)));
#line default
#line hidden
#line 382 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 381 "..\..\Views\User\UserParts\_Subject.cshtml"
}
else
@@ -1358,14 +1365,14 @@ WriteLiteral(" data-clipboard>\r\n");
#line default
#line hidden
#line 386 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 385 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(assignment.Device.SerialNumber);
#line default
#line hidden
#line 386 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 385 "..\..\Views\User\UserParts\_Subject.cshtml"
}
@@ -1375,13 +1382,13 @@ WriteLiteral(" data-clipboard>\r\n");
WriteLiteral(" </span>\r\n");
#line 389 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 388 "..\..\Views\User\UserParts\_Subject.cshtml"
#line default
#line hidden
#line 389 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 388 "..\..\Views\User\UserParts\_Subject.cshtml"
if (!string.IsNullOrWhiteSpace(assignment.Device.ComputerName))
{
@@ -1397,7 +1404,7 @@ WriteLiteral(" class=\"User_Show_AssignedDevices_CurrentAssignment_ComputerName\
WriteLiteral(" data-clipboard>");
#line 391 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 390 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(assignment.Device.ComputerName);
@@ -1408,7 +1415,7 @@ WriteLiteral("</span>)");
WriteLiteral("\r\n");
#line 392 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 391 "..\..\Views\User\UserParts\_Subject.cshtml"
}
@@ -1418,13 +1425,13 @@ WriteLiteral(" </td>\r\n
" </tr>\r\n");
#line 395 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 394 "..\..\Views\User\UserParts\_Subject.cshtml"
#line default
#line hidden
#line 395 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 394 "..\..\Views\User\UserParts\_Subject.cshtml"
if (!string.IsNullOrEmpty(assignment.Device.AssetNumber))
{
@@ -1441,7 +1448,7 @@ WriteLiteral(" class=\"User_Show_AssignedDevices_CurrentAssignment_Asset\"");
WriteLiteral(" data-clipboard>");
#line 400 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 399 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(assignment.Device.AssetNumber);
@@ -1451,7 +1458,7 @@ WriteLiteral("</span>\r\n
" </tr>\r\n");
#line 403 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 402 "..\..\Views\User\UserParts\_Subject.cshtml"
}
@@ -1460,7 +1467,7 @@ WriteLiteral("</span>\r\n
WriteLiteral(" ");
#line 404 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 403 "..\..\Views\User\UserParts\_Subject.cshtml"
if (assignment.Device.DeviceModelId.HasValue)
{
@@ -1479,7 +1486,7 @@ WriteLiteral(" class=\"User_Show_AssignedDevices_CurrentAssignment_Model\"");
WriteLiteral(">");
#line 411 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 410 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(assignment.Device.DeviceModel.ToString());
@@ -1489,7 +1496,7 @@ WriteLiteral("</span>\r\n
" </tr>\r\n");
#line 414 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 413 "..\..\Views\User\UserParts\_Subject.cshtml"
}
@@ -1507,7 +1514,7 @@ WriteLiteral(" class=\"User_Show_AssignedDevices_CurrentAssignment_Profile\"");
WriteLiteral(">");
#line 420 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 419 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(assignment.Device.DeviceProfile.ToString());
@@ -1517,13 +1524,13 @@ WriteLiteral("</span>\r\n
" </tr>\r\n");
#line 423 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 422 "..\..\Views\User\UserParts\_Subject.cshtml"
#line default
#line hidden
#line 423 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 422 "..\..\Views\User\UserParts\_Subject.cshtml"
if (assignment.Device.DeviceBatchId.HasValue)
{
@@ -1542,7 +1549,7 @@ WriteLiteral(" class=\"User_Show_AssignedDevices_CurrentAssignment_Batch\"");
WriteLiteral(">");
#line 430 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 429 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(assignment.Device.DeviceBatch.ToString());
@@ -1552,7 +1559,7 @@ WriteLiteral("</span>\r\n
" </tr>\r\n");
#line 433 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 432 "..\..\Views\User\UserParts\_Subject.cshtml"
}
@@ -1568,7 +1575,7 @@ WriteLiteral(" class=\"User_Show_AssignedDevices_CurrentAssignment_Assigned\"");
WriteLiteral(">");
#line 437 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 436 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(CommonHelpers.FriendlyDate(assignment.AssignedDate));
@@ -1578,15 +1585,14 @@ WriteLiteral("</span>\r\n
" </tr>\r\n");
#line 440 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 439 "..\..\Views\User\UserParts\_Subject.cshtml"
#line default
#line hidden
#line 440 "..\..\Views\User\UserParts\_Subject.cshtml"
if (Authorization.Has(Claims.Device.ShowFlagAssignments) &&
assignment.Device.DeviceFlagAssignments.Any(a => a.RemovedDate.HasValue))
#line 439 "..\..\Views\User\UserParts\_Subject.cshtml"
if (assignment.Device.DeviceFlagAssignments.CanShowAny())
{
@@ -1604,50 +1610,52 @@ WriteLiteral(" class=\"User_Show_Assigned_Devices_CurrentAssignment_Flags\"");
WriteLiteral(">\r\n");
#line 446 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 444 "..\..\Views\User\UserParts\_Subject.cshtml"
#line default
#line hidden
#line 446 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 444 "..\..\Views\User\UserParts\_Subject.cshtml"
foreach (var flag in assignment.Device.DeviceFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, DeviceFlagService.GetDeviceFlag(f.DeviceFlagId))))
{
if (flag.Item2.permission.CanShow())
{
#line default
#line hidden
WriteLiteral(" <i");
WriteLiteral(" <i");
WriteAttribute("class", Tuple.Create(" class=\"", 30837), Tuple.Create("\"", 30907)
, Tuple.Create(Tuple.Create("", 30845), Tuple.Create("flag", 30845), true)
, Tuple.Create(Tuple.Create(" ", 30849), Tuple.Create("fa", 30850), true)
, Tuple.Create(Tuple.Create(" ", 30852), Tuple.Create("fa-", 30853), true)
WriteAttribute("class", Tuple.Create(" class=\"", 30707), Tuple.Create("\"", 30787)
, Tuple.Create(Tuple.Create("", 30715), Tuple.Create("flag", 30715), true)
, Tuple.Create(Tuple.Create(" ", 30719), Tuple.Create("fa", 30720), true)
, Tuple.Create(Tuple.Create(" ", 30722), Tuple.Create("fa-", 30723), true)
#line 448 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 30856), Tuple.Create<System.Object, System.Int32>(flag.Item2.Icon
, Tuple.Create(Tuple.Create("", 30726), Tuple.Create<System.Object, System.Int32>(flag.Item2.flag.Icon
#line default
#line hidden
, 30856), false)
, Tuple.Create(Tuple.Create(" ", 30874), Tuple.Create("fa-fw", 30875), true)
, Tuple.Create(Tuple.Create(" ", 30880), Tuple.Create("d-", 30881), true)
, 30726), false)
, Tuple.Create(Tuple.Create(" ", 30749), Tuple.Create("fa-fw", 30750), true)
, Tuple.Create(Tuple.Create(" ", 30755), Tuple.Create("d-", 30756), true)
#line 448 "..\..\Views\User\UserParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 30883), Tuple.Create<System.Object, System.Int32>(flag.Item2.IconColour
, Tuple.Create(Tuple.Create("", 30758), Tuple.Create<System.Object, System.Int32>(flag.Item2.flag.IconColour
#line default
#line hidden
, 30883), false)
, 30758), false)
);
WriteLiteral(">\r\n <s" +
"pan");
WriteLiteral(">\r\n " +
" <span");
WriteLiteral(" class=\"details\"");
WriteLiteral(">\r\n " +
" <span");
" <span");
WriteLiteral(" class=\"name\"");
@@ -1655,7 +1663,7 @@ WriteLiteral(">");
#line 450 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(flag.Item2.Name);
Write(flag.Item2.flag.Name);
#line default
@@ -1664,8 +1672,8 @@ WriteLiteral("</span>");
#line 450 "..\..\Views\User\UserParts\_Subject.cshtml"
if (flag.Item1.Comments != null)
{
if (flag.Item1.Comments != null)
{
#line default
#line hidden
@@ -1677,7 +1685,7 @@ WriteLiteral(">");
#line 451 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(flag.Item1.Comments.ToHtmlComment());
Write(flag.Item1.Comments.ToHtmlComment());
#line default
@@ -1686,7 +1694,7 @@ WriteLiteral("</span>");
#line 451 "..\..\Views\User\UserParts\_Subject.cshtml"
}
}
#line default
#line hidden
@@ -1698,17 +1706,18 @@ WriteLiteral(">");
#line 451 "..\..\Views\User\UserParts\_Subject.cshtml"
Write(CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId));
Write(CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId));
#line default
#line hidden
WriteLiteral("</span>\r\n " +
" </span>\r\n " +
" </i>\r\n");
" </span>\r\n " +
" </i>\r\n");
#line 454 "..\..\Views\User\UserParts\_Subject.cshtml"
}
}
@@ -1761,7 +1770,7 @@ WriteLiteral(">\r\n
" </tr>\r\n");
#line 488 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 489 "..\..\Views\User\UserParts\_Subject.cshtml"
}
@@ -1772,7 +1781,7 @@ WriteLiteral(" </tbody>\r\n
" </div>\r\n");
#line 493 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 494 "..\..\Views\User\UserParts\_Subject.cshtml"
}
}
else
@@ -1788,7 +1797,7 @@ WriteLiteral(" class=\"smallMessage\"");
WriteLiteral(">No Current Device Assignments</span>\r\n");
#line 498 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 499 "..\..\Views\User\UserParts\_Subject.cshtml"
}
@@ -1798,7 +1807,7 @@ WriteLiteral(" </div>\r\n </div>\r\n
"\r\n");
#line 502 "..\..\Views\User\UserParts\_Subject.cshtml"
#line 503 "..\..\Views\User\UserParts\_Subject.cshtml"
}
+9 -9
View File
@@ -42,22 +42,22 @@
{
@item.FriendlyId
}
@if (Authorization.Has(Claims.User.ShowFlagAssignments))
@if (item.UserFlagAssignments.CanShowAny())
{
@if (item.UserFlagAssignments != null && item.UserFlagAssignments.Count > 0)
{
<div class="flags">
@foreach (var flag in item.UserFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, UserFlagService.GetUserFlag(f.UserFlagId))))
<div class="flags">
@foreach (var flag in item.UserFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, UserFlagService.GetUserFlag(f.UserFlagId))))
{
if (flag.Item2.permission.CanShow())
{
<i class="flag fa fa-@(flag.Item2.Icon) fa-fw d-@(flag.Item2.IconColour)">
<i class="flag fa fa-@(flag.Item2.flag.Icon) fa-fw d-@(flag.Item2.flag.IconColour)">
<span class="details">
<span class="name">@flag.Item2.Name</span>@if (flag.Item1.Comments != null)
<span class="name">@flag.Item2.flag.Name</span>@if (flag.Item1.Comments != null)
{<span class="comments">@flag.Item1.Comments.ToHtmlComment()</span>}<span class="added">@CommonHelpers.FriendlyDateAndUser(flag.Item1.AddedDate, flag.Item1.AddedUserId)</span>
</span>
</i>
}
</div>
}
}
</div>
}
</td>
<td>
+23 -34
View File
@@ -173,35 +173,29 @@ WriteLiteral(" ");
#line 45 "..\..\Views\User\_UserTable.cshtml"
if (Authorization.Has(Claims.User.ShowFlagAssignments))
if (item.UserFlagAssignments.CanShowAny())
{
#line default
#line hidden
#line 47 "..\..\Views\User\_UserTable.cshtml"
if (item.UserFlagAssignments != null && item.UserFlagAssignments.Count > 0)
{
#line default
#line hidden
WriteLiteral(" <div");
WriteLiteral(" <div");
WriteLiteral(" class=\"flags\"");
WriteLiteral(">\r\n");
#line 50 "..\..\Views\User\_UserTable.cshtml"
#line 48 "..\..\Views\User\_UserTable.cshtml"
#line default
#line hidden
#line 50 "..\..\Views\User\_UserTable.cshtml"
foreach (var flag in item.UserFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, UserFlagService.GetUserFlag(f.UserFlagId))))
#line 48 "..\..\Views\User\_UserTable.cshtml"
foreach (var flag in item.UserFlagAssignments.Where(f => !f.RemovedDate.HasValue).Select(f => Tuple.Create(f, UserFlagService.GetUserFlag(f.UserFlagId))))
{
if (flag.Item2.permission.CanShow())
{
@@ -209,26 +203,26 @@ WriteLiteral(">\r\n");
#line hidden
WriteLiteral(" <i");
WriteAttribute("class", Tuple.Create(" class=\"", 2064), Tuple.Create("\"", 2134)
, Tuple.Create(Tuple.Create("", 2072), Tuple.Create("flag", 2072), true)
, Tuple.Create(Tuple.Create(" ", 2076), Tuple.Create("fa", 2077), true)
, Tuple.Create(Tuple.Create(" ", 2079), Tuple.Create("fa-", 2080), true)
WriteAttribute("class", Tuple.Create(" class=\"", 2015), Tuple.Create("\"", 2095)
, Tuple.Create(Tuple.Create("", 2023), Tuple.Create("flag", 2023), true)
, Tuple.Create(Tuple.Create(" ", 2027), Tuple.Create("fa", 2028), true)
, Tuple.Create(Tuple.Create(" ", 2030), Tuple.Create("fa-", 2031), true)
#line 52 "..\..\Views\User\_UserTable.cshtml"
, Tuple.Create(Tuple.Create("", 2083), Tuple.Create<System.Object, System.Int32>(flag.Item2.Icon
, Tuple.Create(Tuple.Create("", 2034), Tuple.Create<System.Object, System.Int32>(flag.Item2.flag.Icon
#line default
#line hidden
, 2083), false)
, Tuple.Create(Tuple.Create(" ", 2101), Tuple.Create("fa-fw", 2102), true)
, Tuple.Create(Tuple.Create(" ", 2107), Tuple.Create("d-", 2108), true)
, 2034), false)
, Tuple.Create(Tuple.Create(" ", 2057), Tuple.Create("fa-fw", 2058), true)
, Tuple.Create(Tuple.Create(" ", 2063), Tuple.Create("d-", 2064), true)
#line 52 "..\..\Views\User\_UserTable.cshtml"
, Tuple.Create(Tuple.Create("", 2110), Tuple.Create<System.Object, System.Int32>(flag.Item2.IconColour
, Tuple.Create(Tuple.Create("", 2066), Tuple.Create<System.Object, System.Int32>(flag.Item2.flag.IconColour
#line default
#line hidden
, 2110), false)
, 2066), false)
);
WriteLiteral(">\r\n <span");
@@ -243,7 +237,7 @@ WriteLiteral(">");
#line 54 "..\..\Views\User\_UserTable.cshtml"
Write(flag.Item2.Name);
Write(flag.Item2.flag.Name);
#line default
@@ -252,7 +246,7 @@ WriteLiteral("</span>");
#line 54 "..\..\Views\User\_UserTable.cshtml"
if (flag.Item1.Comments != null)
if (flag.Item1.Comments != null)
{
#line default
@@ -297,20 +291,15 @@ WriteLiteral("</span>\r\n </span>
#line 58 "..\..\Views\User\_UserTable.cshtml"
}
}
#line default
#line hidden
WriteLiteral("\r\n </div>\r\n");
WriteLiteral(" </div>\r\n");
#line 60 "..\..\Views\User\_UserTable.cshtml"
}
#line default
#line hidden
#line 60 "..\..\Views\User\_UserTable.cshtml"
#line 61 "..\..\Views\User\_UserTable.cshtml"
}