//
using System;
+using System.Collections;
+using System.Security.Principal;
+using System.Text;
+using System.Threading;
namespace System.Security.Permissions {
[Serializable]
public sealed class PrincipalPermission : IPermission, IUnrestrictedPermission {
- private string _name;
- private string _role;
- private bool _isAuthenticated;
+ internal class PrincipalInfo {
+
+ private string _name;
+ private string _role;
+ private bool _isAuthenticated;
+
+ public PrincipalInfo (string name, string role, bool isAuthenticated) {
+ _name = name;
+ _role = role;
+ _isAuthenticated = isAuthenticated;
+ }
+
+ public string Name {
+ get { return _name; }
+ }
+
+ public string Role {
+ get { return _role; }
+ }
+
+ public bool IsAuthenticated {
+ get { return _isAuthenticated; }
+ }
+ }
+
+ private ArrayList principals;
// Constructors
public PrincipalPermission (PermissionState state)
{
+ principals = new ArrayList ();
+ switch (state) {
+ case PermissionState.None:
+ break;
+ case PermissionState.Unrestricted:
+ PrincipalInfo pi = new PrincipalInfo (null, null, true);
+ principals.Add (pi);
+ break;
+ default:
+ throw new ArgumentException ("unknown PermissionState");
+ }
}
- public PrincipalPermission (string name, string role)
+ public PrincipalPermission (string name, string role) : this (name, role, true)
{
}
public PrincipalPermission (string name, string role, bool isAuthenticated)
{
+ principals = new ArrayList ();
+ PrincipalInfo pi = new PrincipalInfo (name, role, isAuthenticated);
+ principals.Add (pi);
+ }
+
+ internal PrincipalPermission (ArrayList principals)
+ {
+ this.principals = principals;
}
// Properties
public IPermission Copy ()
{
- return new PrincipalPermission (_name, _role, _isAuthenticated);
+ return new PrincipalPermission (principals);
}
- [MonoTODO]
- public void Demand ()
+ public void Demand ()
{
+ IPrincipal p = Thread.CurrentPrincipal;
+ if (p == null)
+ throw new SecurityException ("no Principal");
+
+ if (principals.Count > 0) {
+ // check restrictions
+ bool demand = false;
+ foreach (PrincipalInfo pi in principals) {
+ // if a name is present then it must be equal
+ // if a role is present then the identity must be a member of this role
+ // if authentication is required then the identity must be authenticated
+ if (((pi.Name == null) || (pi.Name == p.Identity.Name)) &&
+ ((pi.Role == null) || (p.IsInRole (pi.Role))) &&
+ ((pi.IsAuthenticated && p.Identity.IsAuthenticated) || (!pi.IsAuthenticated))) {
+ demand = true;
+ break;
+ }
+ }
+
+ if (!demand)
+ throw new SecurityException ("invalid Principal");
+ }
}
- [MonoTODO]
public void FromXml (SecurityElement esd)
{
+ if (esd == null)
+ throw new ArgumentNullException ("esd");
+ if (esd.Tag != "IPermission")
+ throw new ArgumentException ("not IPermission");
+ if (!(esd.Attributes ["class"] as string).StartsWith ("System.Security.Permissions.PrincipalPermission"))
+ throw new ArgumentException ("not PrincipalPermission");
+ if ((esd.Attributes ["version"] as string) != "1")
+ throw new ArgumentException ("wrong version");
+
+ // Children is null, not empty, when no child is present
+ if (esd.Children != null) {
+ foreach (SecurityElement se in esd.Children) {
+ if (se.Tag != "Identity")
+ throw new ArgumentException ("not IPermission/Identity");
+ string name = (se.Attributes ["Name"] as string);
+ string role = (se.Attributes ["Role"] as string);
+ bool isAuthenticated = ((se.Attributes ["Authenticated"] as string) == "true");
+ PrincipalInfo pi = new PrincipalInfo (name, role, isAuthenticated);
+ principals.Add (pi);
+ }
+ }
}
- [MonoTODO]
public IPermission Intersect (IPermission target)
{
- return null;
+ if (target == null)
+ return null;
+ if (! (target is PrincipalPermission))
+ throw new ArgumentException ("wrong type");
+
+ PrincipalPermission o = (PrincipalPermission) target;
+ if (IsUnrestricted ())
+ return o.Copy ();
+ if (o.IsUnrestricted ())
+ return Copy ();
+
+ PrincipalPermission intersect = new PrincipalPermission (PermissionState.None);
+ foreach (PrincipalInfo pi in principals) {
+ foreach (PrincipalInfo opi in o.principals) {
+ if (pi.IsAuthenticated == opi.IsAuthenticated) {
+ string name = null;
+ if ((pi.Name == opi.Name) || (opi.Name == null))
+ name = pi.Name;
+ string role = null;
+ if ((pi.Role == opi.Role) || (opi.Role == null))
+ role = pi.Role;
+ if ((name != null) || (role != null)) {
+ PrincipalInfo ipi = new PrincipalInfo (name, role, pi.IsAuthenticated);
+ intersect.principals.Add (ipi);
+ }
+ }
+ }
+ }
+
+ return ((intersect.principals.Count > 0) ? intersect : null);
}
- [MonoTODO]
public bool IsSubsetOf (IPermission target)
{
- return false;
+ if (target == null)
+ return false;
+
+ if (! (target is PrincipalPermission))
+ throw new ArgumentException ("wrong type");
+
+ PrincipalPermission o = (PrincipalPermission) target;
+ if (IsUnrestricted ())
+ return o.IsUnrestricted ();
+ else if (o.IsUnrestricted ())
+ return true;
+
+ // each must be a subset of the target
+ foreach (PrincipalInfo pi in principals) {
+ bool thisItem = false;
+ foreach (PrincipalInfo opi in o.principals) {
+ if (((pi.Name == opi.Name) || (opi.Name == null)) &&
+ ((pi.Role == opi.Role) || (opi.Role == null)) &&
+ (pi.IsAuthenticated == opi.IsAuthenticated))
+ thisItem = true;
+ }
+ if (!thisItem)
+ return false;
+ }
+
+ return true;
}
- [MonoTODO]
public bool IsUnrestricted ()
{
+ foreach (PrincipalInfo pi in principals) {
+ if ((pi.Name == null) && (pi.Role == null) && (pi.IsAuthenticated))
+ return true;
+ }
return false;
}
- [MonoTODO]
public override string ToString ()
{
- return null;
+ return ToXml ().ToString ();
}
- [MonoTODO]
public SecurityElement ToXml ()
{
- return null;
+ SecurityElement se = new SecurityElement ("IPermission");
+ Type type = this.GetType ();
+ StringBuilder asmName = new StringBuilder (type.Assembly.ToString ());
+ asmName.Replace ('\"', '\'');
+ se.AddAttribute ("class", type.FullName + ", " + asmName);
+ se.AddAttribute ("version", "1");
+ foreach (PrincipalInfo pi in principals) {
+ SecurityElement sec = new SecurityElement ("Identity");
+ if (pi.Name != null)
+ sec.AddAttribute ("Name", pi.Name);
+ if (pi.Role != null)
+ sec.AddAttribute ("Role", pi.Role);
+ if (pi.IsAuthenticated)
+ sec.AddAttribute ("Authenticated", "true");
+ se.AddChild (sec);
+ }
+ return se;
}
- [MonoTODO]
public IPermission Union (IPermission target)
{
- return null;
+ if (target == null)
+ return Copy ();
+ if (! (target is PrincipalPermission))
+ throw new ArgumentException ("wrong type");
+
+ PrincipalPermission o = (PrincipalPermission) target;
+ if (IsUnrestricted () || o.IsUnrestricted ())
+ return new PrincipalPermission (PermissionState.Unrestricted);
+
+ PrincipalPermission union = new PrincipalPermission (principals);
+ foreach (PrincipalInfo pi in o.principals)
+ principals.Add (pi);
+
+ return union;
}
}
}
\ No newline at end of file