Skip to content

Commit 79754bf

Browse files
authored
Fix: Fixed an issue where it wasn't possible to edit some file permissions (#12142)
1 parent 8707b94 commit 79754bf

17 files changed

+923
-702
lines changed

src/Files.App/Filesystem/Security/AccessControlEntry.cs

Lines changed: 144 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -13,56 +13,144 @@
1313
namespace Files.App.Filesystem.Security
1414
{
1515
/// <summary>
16-
/// Represents an ACE.
16+
/// Represents an access control entry (ACE).
1717
/// </summary>
1818
public class AccessControlEntry : ObservableObject
1919
{
20-
public bool IsFolder { get; set; }
21-
20+
/// <summary>
21+
/// Whether the path indicates folder or not
22+
/// </summary>
23+
public bool IsFolder { get; private set; }
24+
25+
/// <summary>
26+
/// The owner in the security descriptor (SD).
27+
/// NULL if the security descriptor has no owner SID.
28+
/// </summary>
2229
public Principal Principal { get; set; }
2330

24-
private AccessControlType _AccessControlType;
25-
public AccessControlType AccessControlType
31+
/// <summary>
32+
/// Whether the ACE is inherited or not
33+
/// </summary>
34+
public bool IsInherited { get; private set; }
35+
36+
/// <summary>
37+
/// Whether the ACE is editable or not
38+
/// </summary>
39+
public bool IsEditable
40+
=> IsSelected && !IsInherited && false;
41+
42+
/// <summary>
43+
/// AccessControlTypeHumanized
44+
/// </summary>
45+
public string AccessControlTypeHumanized
46+
=> AccessControlType switch
47+
{
48+
AccessControlEntryType.Allow => "Allow",
49+
_ => "Deny" // AccessControlType.Deny
50+
};
51+
52+
/// <summary>
53+
/// AccessControlTypeGlyph
54+
/// </summary>
55+
public string AccessControlTypeGlyph
56+
=> AccessControlType switch
57+
{
58+
AccessControlEntryType.Allow => "\xE73E",
59+
_ => "\xF140" // AccessControlType.Deny
60+
};
61+
62+
/// <summary>
63+
/// AccessMaskFlagsHumanized
64+
/// </summary>
65+
public string AccessMaskFlagsHumanized
2666
{
27-
get => _AccessControlType;
28-
set
67+
get
2968
{
30-
// Update access control type glyph
31-
if (SetProperty(ref _AccessControlType, value))
32-
OnPropertyChanged(nameof(AccessControlTypeGlyph));
69+
var accessMaskStrings = new List<string>();
70+
71+
if (AccessMaskFlags == AccessMaskFlags.NULL)
72+
accessMaskStrings.Add("None".GetLocalizedResource());
73+
74+
if (FullControlAccess)
75+
accessMaskStrings.Add("SecurityFullControlLabel/Text".GetLocalizedResource());
76+
else if (ModifyAccess)
77+
accessMaskStrings.Add("SecurityModifyLabel/Text".GetLocalizedResource());
78+
else if (ReadAndExecuteAccess)
79+
accessMaskStrings.Add("SecurityReadAndExecuteLabel/Text".GetLocalizedResource());
80+
else if (ReadAccess)
81+
accessMaskStrings.Add("SecurityReadLabel/Text".GetLocalizedResource());
82+
83+
if (!FullControlAccess && !ModifyAccess && WriteAccess)
84+
accessMaskStrings.Add("Write".GetLocalizedResource());
85+
86+
if (SpecialAccess)
87+
accessMaskStrings.Add("SecuritySpecialLabel/Text".GetLocalizedResource());
88+
89+
return string.Join(", ", accessMaskStrings);
3390
}
3491
}
3592

36-
private AccessMaskFlags _AccessMaskFlags;
37-
public AccessMaskFlags AccessMaskFlags
93+
/// <summary>
94+
/// IsInheritedHumanized
95+
/// </summary>
96+
public string IsInheritedHumanized
97+
=> IsInherited ? "Yes".GetLocalizedResource() : "No".GetLocalizedResource();
98+
99+
/// <summary>
100+
/// InheritanceFlagsHumanized
101+
/// </summary>
102+
public string InheritanceFlagsHumanized
38103
{
39-
get => _AccessMaskFlags;
40-
set
104+
get
41105
{
42-
if (SetProperty(ref _AccessMaskFlags, value))
43-
OnPropertyChanged(nameof(AccessMaskFlagsHumanized));
106+
var inheritanceStrings = new List<string>();
107+
108+
if (AccessControlEntryFlags == AccessControlEntryFlags.None ||
109+
AccessControlEntryFlags == AccessControlEntryFlags.NoPropagateInherit)
110+
inheritanceStrings.Add("SecurityAdvancedFlagsFolderLabel".GetLocalizedResource());
111+
112+
if (AccessControlEntryFlags.HasFlag(AccessControlEntryFlags.ContainerInherit))
113+
inheritanceStrings.Add("SecurityAdvancedFlagsSubfoldersLabel".GetLocalizedResource());
114+
115+
if (AccessControlEntryFlags.HasFlag(AccessControlEntryFlags.ObjectInherit))
116+
inheritanceStrings.Add("SecurityAdvancedFlagsFilesLabel".GetLocalizedResource());
117+
118+
// Capitalize the first letter
119+
if (inheritanceStrings.Any())
120+
inheritanceStrings[0] = char.ToUpperInvariant(inheritanceStrings[0].First()) + inheritanceStrings[0][1..];
121+
122+
return string.Join(", ", inheritanceStrings);
44123
}
45124
}
46125

47-
private InheritanceFlags _InheritanceFlags;
48-
public InheritanceFlags InheritanceFlags
126+
/// <summary>
127+
/// AccessMaskItems
128+
/// </summary>
129+
public ObservableCollection<AccessMaskItem> AccessMaskItems { get; set; }
130+
131+
private AccessControlEntryType _AccessControlType;
132+
public AccessControlEntryType AccessControlType
49133
{
50-
get => _InheritanceFlags;
134+
get => _AccessControlType;
51135
set
52136
{
53-
if (SetProperty(ref _InheritanceFlags, value))
54-
OnPropertyChanged(nameof(InheritanceFlagsHumanized));
137+
if (SetProperty(ref _AccessControlType, value))
138+
{
139+
OnPropertyChanged(nameof(AccessControlTypeGlyph));
140+
OnPropertyChanged(nameof(AccessControlTypeHumanized));
141+
}
55142
}
56143
}
57144

58-
private PropagationFlags _PropagationFlags;
59-
public PropagationFlags PropagationFlags
145+
#region Access Mask Properties
146+
private AccessMaskFlags _AccessMaskFlags;
147+
public AccessMaskFlags AccessMaskFlags
60148
{
61-
get => _PropagationFlags;
149+
get => _AccessMaskFlags;
62150
set
63151
{
64-
if (SetProperty(ref _PropagationFlags, value))
65-
OnPropertyChanged(nameof(InheritanceFlagsHumanized));
152+
if (SetProperty(ref _AccessMaskFlags, value))
153+
OnPropertyChanged(nameof(AccessMaskFlagsHumanized));
66154
}
67155
}
68156

@@ -102,9 +190,21 @@ public AccessMaskFlags DeniedAccessMaskFlags
102190
}
103191
}
104192

193+
private AccessControlEntryFlags _InheritanceFlags;
194+
public AccessControlEntryFlags AccessControlEntryFlags
195+
{
196+
get => _InheritanceFlags;
197+
set
198+
{
199+
if (SetProperty(ref _InheritanceFlags, value))
200+
OnPropertyChanged(nameof(InheritanceFlagsHumanized));
201+
}
202+
}
203+
105204
public AccessMaskFlags InheritedAllowAccessMaskFlags { get; set; }
106205

107206
public AccessMaskFlags InheritedDenyAccessMaskFlags { get; set; }
207+
#endregion
108208

109209
private bool _IsSelected;
110210
public bool IsSelected
@@ -114,10 +214,9 @@ public bool IsSelected
114214
{
115215
if (SetProperty(ref _IsSelected, value))
116216
{
117-
if (!value)
118-
AreAdvancedPermissionsShown = false;
217+
AreAdvancedPermissionsShown = false;
119218

120-
OnPropertyChanged(nameof(IsEditEnabled));
219+
OnPropertyChanged(nameof(IsEditable));
121220
}
122221
}
123222
}
@@ -130,86 +229,10 @@ public bool AreAdvancedPermissionsShown
130229
{
131230
// Reinitialize list
132231
if (SetProperty(ref _AreAdvancedPermissionsShown, value))
133-
AccessMaskItemList = SecurityAdvancedAccessControlItemFactory.Initialize(this, AreAdvancedPermissionsShown, IsInherited, IsFolder);
232+
AccessMaskItems = SecurityAdvancedAccessControlItemFactory.Initialize(this, value, IsInherited, IsFolder);
134233
}
135234
}
136235

137-
public bool IsInherited { get; set; }
138-
139-
public bool IsEditEnabled
140-
=> IsSelected && !IsInherited;
141-
142-
public string AccessControlTypeHumanized
143-
=> AccessControlType switch
144-
{
145-
AccessControlType.Allow => "Allow",
146-
_ => "Deny" // AccessControlType.Deny
147-
};
148-
149-
public string AccessControlTypeGlyph
150-
=> AccessControlType switch
151-
{
152-
AccessControlType.Allow => "\xE73E",
153-
_ => "\xF140" // AccessControlType.Deny
154-
};
155-
156-
public string AccessMaskFlagsHumanized
157-
{
158-
get
159-
{
160-
var accessMaskStrings = new List<string>();
161-
162-
if (AccessMaskFlags == AccessMaskFlags.NULL)
163-
accessMaskStrings.Add("None".GetLocalizedResource());
164-
165-
if (FullControlAccess)
166-
accessMaskStrings.Add("SecurityFullControlLabel/Text".GetLocalizedResource());
167-
else if (ModifyAccess)
168-
accessMaskStrings.Add("SecurityModifyLabel/Text".GetLocalizedResource());
169-
else if (ReadAndExecuteAccess)
170-
accessMaskStrings.Add("SecurityReadAndExecuteLabel/Text".GetLocalizedResource());
171-
else if (ReadAccess)
172-
accessMaskStrings.Add("SecurityReadLabel/Text".GetLocalizedResource());
173-
174-
if (!FullControlAccess && !ModifyAccess && WriteAccess)
175-
accessMaskStrings.Add("Write".GetLocalizedResource());
176-
177-
if (SpecialAccess)
178-
accessMaskStrings.Add("SecuritySpecialLabel/Text".GetLocalizedResource());
179-
180-
return string.Join(",", accessMaskStrings);
181-
}
182-
}
183-
184-
public string IsInheritedHumanized
185-
=> IsInherited ? "Yes".GetLocalizedResource() : "No".GetLocalizedResource();
186-
187-
public string InheritanceFlagsHumanized
188-
{
189-
get
190-
{
191-
var inheritanceStrings = new List<string>();
192-
193-
if (PropagationFlags == PropagationFlags.None ||
194-
PropagationFlags == PropagationFlags.NoPropagateInherit)
195-
inheritanceStrings.Add("SecurityAdvancedFlagsFolderLabel".GetLocalizedResource());
196-
197-
if (InheritanceFlags.HasFlag(InheritanceFlags.ContainerInherit))
198-
inheritanceStrings.Add("SecurityAdvancedFlagsSubfoldersLabel".GetLocalizedResource());
199-
200-
if (InheritanceFlags.HasFlag(InheritanceFlags.ObjectInherit))
201-
inheritanceStrings.Add("SecurityAdvancedFlagsFilesLabel".GetLocalizedResource());
202-
203-
// Capitalize first letter
204-
if (inheritanceStrings.Any())
205-
inheritanceStrings[0] = char.ToUpperInvariant(inheritanceStrings[0].First()) + inheritanceStrings[0][1..];
206-
207-
return string.Join(",", inheritanceStrings);
208-
}
209-
}
210-
211-
public ObservableCollection<AccessMaskItem> AccessMaskItemList { get; set; }
212-
213236
#region Security page
214237
public bool WriteAccess => AccessMaskFlags.HasFlag(AccessMaskFlags.Write);
215238
public bool ReadAccess => AccessMaskFlags.HasFlag(AccessMaskFlags.Read);
@@ -318,40 +341,37 @@ public bool DeniedFullControlAccess
318341
public IRelayCommand<string> ChangeAccessControlTypeCommand { get; set; }
319342
public IRelayCommand<string> ChangeInheritanceFlagsCommand { get; set; }
320343

321-
public AccessControlEntry(bool isFolder, string ownerSid, AccessControlType type, AccessMaskFlags accessMaskFlags, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
344+
public AccessControlEntry(bool isFolder, string ownerSid, AccessControlEntryType type, AccessMaskFlags accessMaskFlags, bool isInherited, AccessControlEntryFlags inheritanceFlags)
322345
{
323-
AccessMaskItemList = SecurityAdvancedAccessControlItemFactory.Initialize(this, AreAdvancedPermissionsShown, IsInherited, IsFolder);
324-
325-
ChangeAccessControlTypeCommand = new RelayCommand<string>(x =>
326-
{
327-
AccessControlType = Enum.Parse<AccessControlType>(x);
328-
});
346+
AccessMaskItems = SecurityAdvancedAccessControlItemFactory.Initialize(this, AreAdvancedPermissionsShown, IsInherited, IsFolder);
329347

330-
ChangeInheritanceFlagsCommand = new RelayCommand<string>(x =>
331-
{
332-
var parts = x.Split(',');
348+
//ChangeAccessControlTypeCommand = new RelayCommand<string>(x =>
349+
//{
350+
// AccessControlType = Enum.Parse<AccessControlType>(x);
351+
//});
333352

334-
InheritanceFlags = Enum.Parse<InheritanceFlags>(parts[0]);
335-
PropagationFlags = Enum.Parse<PropagationFlags>(parts[1]);
336-
});
353+
//ChangeInheritanceFlagsCommand = new RelayCommand<string>(x =>
354+
//{
355+
// var parts = x.Split(',');
356+
// InheritanceFlags = Enum.Parse<AccessControlEntryFlags>(parts[0]);
357+
//});
337358

338359
IsFolder = isFolder;
339-
Principal = Principal.FromSid(ownerSid);
360+
Principal = new(ownerSid);
340361
AccessControlType = type;
341362
AccessMaskFlags = accessMaskFlags;
342363
IsInherited = isInherited;
343-
InheritanceFlags = inheritanceFlags;
344-
PropagationFlags = propagationFlags;
364+
AccessControlEntryFlags = inheritanceFlags;
345365

346366
switch (AccessControlType)
347367
{
348-
case AccessControlType.Allow:
368+
case AccessControlEntryType.Allow:
349369
if (IsInherited)
350370
InheritedAllowAccessMaskFlags |= AccessMaskFlags;
351371
else
352372
AllowedAccessMaskFlags |= AccessMaskFlags;
353373
break;
354-
case AccessControlType.Deny:
374+
case AccessControlEntryType.Deny:
355375
if (IsInherited)
356376
InheritedDenyAccessMaskFlags |= AccessMaskFlags;
357377
else

0 commit comments

Comments
 (0)