AcUtils
A high performance abstraction layer for AccuRev
AcPermissions.cs
Go to the documentation of this file.
1 
16 using System;
17 using System.Collections.Generic;
18 using System.Threading.Tasks;
19 using System.Xml.Linq;
20 
21 namespace AcUtils
22 {
23  #region enums
24 
25  public enum PermType {
33  group,
36  user,
39  builtin
40  };
41 
46  public enum PermRights
47  {
50  none,
53  all
54  };
55 
60  public enum PermKind
61  {
64  depot,
67  stream
68  };
70  #endregion
71 
76  [Serializable]
77  public sealed class AcPermission : IFormattable, IEquatable<AcPermission>, IComparable<AcPermission>, IComparable
78  {
79  #region class variables
80  private PermKind _kind; // depot or stream
81  private string _name; // name of depot or stream permission applies to
82  private string _appliesTo; // principal of group or user permission applies to or one of the built-in types anyuser or authuser
83  private PermType _type; // whether _appliesTo is a "group", "user", "builtin"
84  private PermRights _rights; // whether permission rights is "all" or "none"
85 
86  // depots: when true permission applies to the depot and its entire stream hierarchy,
87  // when false permission applies only to AccuWork issues in the depot and not its version-controlled elements
88  // streams: when true permission applies to the stream and its entire subhierarchy,
89  // when false permission applies only to the stream
90  private bool _inheritable;
91  #endregion
92 
96  internal AcPermission(PermKind kind)
97  {
98  _kind = kind;
99  }
100 
101  #region Equality comparison
102 
104  public bool Equals(AcPermission other)
112  {
113  if (ReferenceEquals(other, null)) return false;
114  if (ReferenceEquals(this, other)) return true;
115  var left = Tuple.Create(Kind, Name, AppliesTo);
116  var right = Tuple.Create(other.Kind, other.Name, other.AppliesTo);
117  return left.Equals(right);
118  }
119 
124  public override bool Equals(object other)
125  {
126  if (ReferenceEquals(other, null)) return false;
127  if (ReferenceEquals(this, other)) return true;
128  if (GetType() != other.GetType()) return false;
129  return this.Equals(other as AcPermission);
130  }
131 
137  public override int GetHashCode()
138  {
139  var hash = Tuple.Create(Kind, Name, AppliesTo);
140  return hash.GetHashCode();
141  }
143  #endregion
144 
145  #region Order comparison
146 
148 
155  public int CompareTo(AcPermission other)
156  {
157  int result;
158  if (AcPermission.ReferenceEquals(this, other))
159  result = 0;
160  else
161  {
162  result = String.Compare(Name, other.Name);
163  if (result == 0)
164  result = String.Compare(AppliesTo, other.AppliesTo);
165  }
166 
167  return result;
168  }
169 
176  int IComparable.CompareTo(object other)
177  {
178  if (!(other is AcPermission))
179  throw new ArgumentException("Argument is not an AcPermission", "other");
180  AcPermission o = (AcPermission)other;
181  return this.CompareTo(o);
182  }
184  #endregion
185 
189  public PermKind Kind
190  {
191  get { return _kind; }
192  internal set { _kind = value; }
193  }
194 
198  public string Name
199  {
200  get { return _name ?? String.Empty; }
201  internal set { _name = value; }
202  }
203 
208  public string AppliesTo
209  {
210  get { return _appliesTo ?? String.Empty; }
211  internal set { _appliesTo = value; }
212  }
213 
218  public PermType Type
219  {
220  get { return _type; }
221  internal set { _type = value; }
222  }
223 
228  public PermRights Rights
229  {
230  get { return _rights; }
231  internal set { _rights = value; }
232  }
233 
241  public bool Inheritable
242  {
243  get { return _inheritable; }
244  internal set { _inheritable = value; }
245  }
246 
247  #region ToString
248  public string ToString(string format, IFormatProvider provider)
268  {
269  if (provider != null)
270  {
271  ICustomFormatter fmt = provider.GetFormat(this.GetType()) as ICustomFormatter;
272  if (fmt != null)
273  return fmt.Format(format, this, provider);
274  }
275 
276  if (String.IsNullOrEmpty(format))
277  format = "G";
278 
279  switch (format.ToUpperInvariant())
280  {
281  case "G":
282  {
283  string who = $"{((Type == PermType.builtin) ? AppliesTo : Type.ToString() + " " + AppliesTo)}";
284  return $@"Permission on {Name} {Kind} applies to {who} {{{Rights}, {(Inheritable ? "inherit" : "no inherit")}}}";
285  }
286  case "K": // whether the permission pertains to a depot or stream
287  return Kind.ToString();
288  case "N": // name of the depot or stream this permission applies to
289  return Name;
290  case "A": // principal name of the group or user this permission applies to or one of the built-in types "anyuser" or "authuser"
291  return AppliesTo;
292  case "T": // whether AppliesTo is the principal name for a "group", "user", or a "builtin" type
293  return Type.ToString();
294  case "R": // whether permission rights to Name in AppliesTo is "all" or "none"
295  return Rights.ToString();
296 
297  // For a depot, when true permission applies to the depot and its entire
298  // stream hierarchy, when false permission applies only to AccuWork issues
299  // in the depot and not its version-controlled elements.
300  // For a stream, when true permission applies to the stream and its entire
301  // subhierarchy, when false permission applies only to the stream.
302  case "I":
303  return Inheritable.ToString();
304  default:
305  throw new FormatException($"The {format} format string is not supported.");
306  }
307  }
308 
309  // Calls ToString(string, IFormatProvider) version with a null IFormatProvider argument.
310  public string ToString(string format)
311  {
312  return ToString(format, null);
313  }
314 
315  // Calls ToString(string, IFormatProvider) version with the general format
316  // and a null IFormatProvider argument.
317  public override string ToString()
318  {
319  return ToString("G", null);
320  }
321  #endregion ToString
322  }
323 
328  [Serializable]
329  public sealed class AcPermissions : List<AcPermission>
330  {
331  #region class variables
332  private PermKind _kind; // whether the list of permissions held pertain to depots or streams
333  [NonSerialized] private readonly object _locker = new object();
334  #endregion
335 
339  public PermKind Kind
340  {
341  get { return _kind; }
342  internal set { _kind = value; }
343  }
344 
345  #region object construction:
346 
348 
375  public AcPermissions(PermKind kind)
376  {
377  _kind = kind;
378  }
379 
389 
391  public async Task<bool> initAsync(string name = null)
392  {
393  bool ret = false; // assume failure
394  try
395  {
396  AcResult r = await AcCommand.runAsync($@"lsacl -fx {_kind} ""{name}""").ConfigureAwait(false);
397  if (r != null && r.RetVal == 0)
398  {
399  XElement xml = XElement.Parse(r.CmdResult);
400  foreach (XElement e in xml.Elements("Element"))
401  {
402  AcPermission perm = new AcPermission(_kind);
403  perm.Name = (string)e.Attribute("Name");
404  perm.AppliesTo = (string)e.Attribute("Group");
405  string type = (string)e.Attribute("Type");
406  perm.Type = (PermType)Enum.Parse(typeof(PermType), type);
407  string rights = (string)e.Attribute("Rights");
408  perm.Rights = (PermRights)Enum.Parse(typeof(PermRights), rights);
409  perm.Inheritable = (bool)e.Attribute("Inheritable");
410  lock (_locker) { Add(perm); }
411  }
412 
413  ret = true; // operation succeeded
414  }
415  }
416 
417  catch (AcUtilsException ecx)
418  {
419  AcDebug.Log($"AcUtilsException caught and logged in AcPermissions.initAsync{Environment.NewLine}{ecx.Message}");
420  }
421 
422  catch (Exception ecx)
423  {
424  AcDebug.Log($"Exception caught and logged in AcPermissions.initAsync{Environment.NewLine}{ecx.Message}");
425  }
426 
427  return ret;
428  }
430  #endregion
431  }
432 }
string Name
Name of the depot or stream this permission applies to.
PermKind Kind
Whether the list of permissions held pertain to depots or streams.
string ToString(string format, IFormatProvider provider)
The ToString implementation.
AccuRev program return value and command result.
Definition: AcCommand.cs:29
PermRights
Whether permission rights to Name in AppliesTo is all or none.
override int GetHashCode()
Override appropriate for type AcPermission.
AcPermissions(PermKind kind)
A container of AcPermission objects that define AccuRev access control list (ACL) entries...
A permission object that defines the attributes of an AccuRev access control list (ACL) entry...
PermKind
Whether permissions pertain to depots or streams. Set when the permission is created by the setacl co...
string AppliesTo
Principal name of the group or user this permission applies to or one of the built-in types anyuser o...
string CmdResult
The command result (usually XML) emitted by AccuRev.
Definition: AcCommand.cs:70
int RetVal
The AccuRev program return value for the command, otherwise minus one (-1) on error.
Definition: AcCommand.cs:61
static void Log(string message, bool formatting=true)
Write the message text to STDOUT, to weekly log files located in %LOCALAPPDATA%\AcTools\Logs, and to trigger.log in the AccuRev server's ..storage\site_slice\logs folder in the case of triggers.
Definition: AcDebug.cs:378
PermKind Kind
Whether the permission pertains to a depot or stream.
Exception thrown when an AccuRev command fails. The AccuRev program return value is zero (0) on succe...
int CompareTo(AcPermission other)
Generic IComparable implementation (default) for comparing AcPermission objects to sort by Name and t...
AccuRev command processing.
Definition: AcCommand.cs:138
static async Task< AcResult > runAsync(string command, ICmdValidate validator=null)
Run the AccuRev command asynchronously with non-blocking I/O.
Definition: AcCommand.cs:184
Use to log and display error and general purpose text messages, and to save the XML param data sent b...
Definition: AcDebug.cs:100
async Task< bool > initAsync(string name=null)
Populate this container with AcPermission objects.
bool Equals(AcPermission other)
IEquatable implementation to determine the equality of instances of type AcPermission. Uses Kind, Name, and AppliesTo to compare instances.
A container of AcPermission objects that define AccuRev access control list (ACL) entries...
PermType
Whether AppliesTo is the principal name for a group, user, or builtin type.
bool Inheritable
For depots, when true permission applies to the depot and its entire stream hierarchy, when false permission applies only to AccuWork issues in the depot and not its version-controlled elements. For streams, when true permission applies to the stream and its entire subhierarchy, when false permission applies only to the stream.
AcPermission(PermKind kind)
Constructor used during AcPermissions list construction. It is called internally and not by user code...
PermType Type
Whether AppliesTo is the principal name for a group, user, or a builtin type.
PermRights Rights
Whether permission rights to Name in AppliesTo is all or none.
override bool Equals(object other)
Overridden to determine equality.