// System.Security.Permissions.UrlIdentityPermission.cs
//
// Author
-// Sebastien Pouliot <spouliot@motus.com>
+// Sebastien Pouliot <sebastien@ximian.com>
//
// Copyright (C) 2003 Motus Technologies. http://www.motus.com
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
using System.Globalization;
+using System.Runtime.InteropServices;
namespace System.Security.Permissions {
[Serializable]
+ [ComVisible (true)]
public sealed class UrlIdentityPermission : CodeAccessPermission, IBuiltInPermission {
+ private const int version = 1;
+
private string url;
- public UrlIdentityPermission (PermissionState state) : base ()
+ public UrlIdentityPermission (PermissionState state)
{
- if (state != PermissionState.None)
- throw new ArgumentException ("only accept None");
+ // false == do not allow Unrestricted for Identity Permissions
+ CheckPermissionState (state, false);
+ url = String.Empty;
}
- public UrlIdentityPermission (string site) : base ()
+ public UrlIdentityPermission (string site)
{
if (site == null)
throw new ArgumentNullException ("site");
}
public string Url {
- get {
- if (url == null)
- throw new NullReferenceException ("Url");
- return url;
- }
- set { url = value; }
+ get { return url; }
+ set { url = ((value == null) ? String.Empty : value); }
}
-
public override IPermission Copy ()
{
- return new UrlIdentityPermission (url);
+ if (url == null) {
+ return new UrlIdentityPermission (PermissionState.None);
+ }
+ else
+ return new UrlIdentityPermission (url);
}
public override void FromXml (SecurityElement esd)
{
- if (esd == null)
- throw new ArgumentNullException (
- Locale.GetText ("The argument is null."));
-
- if (esd.Attribute ("class") != GetType ().AssemblyQualifiedName)
- throw new ArgumentException (
- Locale.GetText ("The argument is not valid"));
-
- if (esd.Attribute ("version") != "1")
- throw new ArgumentException (
- Locale.GetText ("The argument is not valid"));
-
- url = esd.Attribute ("Url");
+ // General validation in CodeAccessPermission
+ CheckSecurityElement (esd, "esd", 1, 1);
+ // Note: we do not (yet) care about the return value
+ // as we only accept version 1 (min/max values)
+
+ string u = esd.Attribute ("Url");
+ if (u == null)
+ url = String.Empty;
+ else
+ Url = u;
}
- [MonoTODO]
public override IPermission Intersect (IPermission target)
{
// if one permission is null (object or url) then there's no intersection
// if both are null then intersection is null
- if ((target == null) || (url == null))
- return null;
-
- // if non null, target must be of the same type
- if (!(target is UrlIdentityPermission))
- throw new ArgumentNullException ("target");
-
- UrlIdentityPermission targetUrl = (target as UrlIdentityPermission);
- if (targetUrl.Url == null)
+ UrlIdentityPermission uip = Cast (target);
+ if ((uip == null) || (IsEmpty ()))
return null;
-
- // TODO
+ if (Match (uip.url)) {
+ // longest form is the intersection
+ if (url.Length > uip.url.Length)
+ return Copy ();
+ else
+ return uip.Copy ();
+ }
return null;
}
- [MonoTODO]
public override bool IsSubsetOf (IPermission target)
{
- return false;
+ UrlIdentityPermission uip = Cast (target);
+ if (uip == null)
+ return IsEmpty ();
+ if (IsEmpty ())
+ return true;
+ if (uip.url == null)
+ return false;
+
+ // here Match wouldn't work as it is bidirectional
+ int wildcard = uip.url.LastIndexOf ('*');
+ if (wildcard == -1)
+ wildcard = uip.url.Length; // exact match
+
+ return (String.Compare (url, 0, uip.url, 0, wildcard, true, CultureInfo.InvariantCulture) == 0);
}
public override SecurityElement ToXml ()
{
- SecurityElement e = new SecurityElement ("IPermission");
- e.AddAttribute ("class", GetType ().AssemblyQualifiedName);
- e.AddAttribute ("version", "1");
-
- e.AddAttribute ("Url", url);
-
- return e;
+ SecurityElement se = Element (version);
+ if (!IsEmpty ())
+ se.AddAttribute ("Url", url);
+ return se;
}
- [MonoTODO]
public override IPermission Union (IPermission target)
{
- return null;
+ UrlIdentityPermission uip = Cast (target);
+ if (uip == null)
+ return Copy ();
+ if (IsEmpty () && uip.IsEmpty ())
+ return null;
+ if (uip.IsEmpty ())
+ return Copy ();
+ if (IsEmpty ())
+ return uip.Copy ();
+ if (Match (uip.url)) {
+ // shortest form is the union
+ if (url.Length < uip.url.Length)
+ return Copy ();
+ else
+ return uip.Copy ();
+ }
+ throw new ArgumentException (Locale.GetText (
+ "Cannot union two different urls."), "target");
}
// IBuiltInPermission
int IBuiltInPermission.GetTokenIndex ()
{
- return 12;
+ return (int) BuiltInToken.UrlIdentity;
+ }
+
+ // helpers
+
+ private bool IsEmpty ()
+ {
+ return ((url == null) || (url.Length == 0));
+ }
+
+ private UrlIdentityPermission Cast (IPermission target)
+ {
+ if (target == null)
+ return null;
+
+ UrlIdentityPermission uip = (target as UrlIdentityPermission);
+ if (uip == null) {
+ ThrowInvalidPermission (target, typeof (UrlIdentityPermission));
+ }
+
+ return uip;
+ }
+
+ private bool Match (string target)
+ {
+ if ((url == null) || (target == null))
+ return false;
+
+ int wcu = url.LastIndexOf ('*');
+ int wct = target.LastIndexOf ('*');
+ int length = Int32.MaxValue;
+
+ if ((wcu == -1) && (wct == -1)) {
+ // no wildcard, this is an exact match
+ length = Math.Max (url.Length, target.Length);
+ }
+ else if (wcu == -1) {
+ // only "this" has a wildcard, use it
+ length = wct;
+ }
+ else if (wct == -1) {
+ // only "target" has a wildcard, use it
+ length = wcu;
+ }
+ else {
+ // both have wildcards, partial match with the smallest
+ length = Math.Min (wcu, wct);
+ }
+
+ return (String.Compare (url, 0, target, 0, length, true, CultureInfo.InvariantCulture) == 0);
}
}
}