2 // System.Security.Permissions.PrincipalPermission.cs
5 // Sebastien Pouliot <spouliot@motus.com>
7 // Copyright (C) 2003 Motus Technologies. http://www.motus.com
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
35 using System.Security.Principal;
37 using System.Threading;
39 namespace System.Security.Permissions {
42 public sealed class PrincipalPermission : IPermission, IUnrestrictedPermission, IBuiltInPermission {
44 internal class PrincipalInfo {
48 private bool _isAuthenticated;
50 public PrincipalInfo (string name, string role, bool isAuthenticated) {
53 _isAuthenticated = isAuthenticated;
64 public bool IsAuthenticated {
65 get { return _isAuthenticated; }
69 private ArrayList principals;
73 public PrincipalPermission (PermissionState state)
75 principals = new ArrayList ();
77 case PermissionState.None:
79 case PermissionState.Unrestricted:
80 PrincipalInfo pi = new PrincipalInfo (null, null, true);
84 throw new ArgumentException ("unknown PermissionState");
88 public PrincipalPermission (string name, string role) : this (name, role, true)
92 public PrincipalPermission (string name, string role, bool isAuthenticated)
94 principals = new ArrayList ();
95 PrincipalInfo pi = new PrincipalInfo (name, role, isAuthenticated);
99 internal PrincipalPermission (ArrayList principals)
101 this.principals = (ArrayList) principals.Clone ();
108 public IPermission Copy ()
110 return new PrincipalPermission (principals);
113 public void Demand ()
115 IPrincipal p = Thread.CurrentPrincipal;
117 throw new SecurityException ("no Principal");
119 if (principals.Count > 0) {
120 // check restrictions
122 foreach (PrincipalInfo pi in principals) {
123 // if a name is present then it must be equal
124 // if a role is present then the identity must be a member of this role
125 // if authentication is required then the identity must be authenticated
126 if (((pi.Name == null) || (pi.Name == p.Identity.Name)) &&
127 ((pi.Role == null) || (p.IsInRole (pi.Role))) &&
128 ((pi.IsAuthenticated && p.Identity.IsAuthenticated) || (!pi.IsAuthenticated))) {
135 throw new SecurityException ("invalid Principal");
139 public void FromXml (SecurityElement esd)
142 throw new ArgumentNullException ("esd");
143 if (esd.Tag != "IPermission")
144 throw new ArgumentException ("not IPermission");
145 if (!(esd.Attributes ["class"] as string).StartsWith ("System.Security.Permissions.PrincipalPermission"))
146 throw new ArgumentException ("not PrincipalPermission");
147 if ((esd.Attributes ["version"] as string) != "1")
148 throw new ArgumentException ("wrong version");
151 // Children is null, not empty, when no child is present
152 if (esd.Children != null) {
153 foreach (SecurityElement se in esd.Children) {
154 if (se.Tag != "Identity")
155 throw new ArgumentException ("not IPermission/Identity");
156 string name = (se.Attributes ["Name"] as string);
157 string role = (se.Attributes ["Role"] as string);
158 bool isAuthenticated = ((se.Attributes ["Authenticated"] as string) == "true");
159 PrincipalInfo pi = new PrincipalInfo (name, role, isAuthenticated);
165 public IPermission Intersect (IPermission target)
169 if (! (target is PrincipalPermission))
170 throw new ArgumentException ("wrong type");
172 PrincipalPermission o = (PrincipalPermission) target;
173 if (IsUnrestricted ())
175 if (o.IsUnrestricted ())
178 PrincipalPermission intersect = new PrincipalPermission (PermissionState.None);
179 foreach (PrincipalInfo pi in principals) {
180 foreach (PrincipalInfo opi in o.principals) {
181 if (pi.IsAuthenticated == opi.IsAuthenticated) {
183 if ((pi.Name == opi.Name) || (opi.Name == null))
186 if ((pi.Role == opi.Role) || (opi.Role == null))
188 if ((name != null) || (role != null)) {
189 PrincipalInfo ipi = new PrincipalInfo (name, role, pi.IsAuthenticated);
190 intersect.principals.Add (ipi);
196 return ((intersect.principals.Count > 0) ? intersect : null);
199 public bool IsSubsetOf (IPermission target)
204 if (! (target is PrincipalPermission))
205 throw new ArgumentException ("wrong type");
207 PrincipalPermission o = (PrincipalPermission) target;
208 if (IsUnrestricted ())
209 return o.IsUnrestricted ();
210 else if (o.IsUnrestricted ())
213 // each must be a subset of the target
214 foreach (PrincipalInfo pi in principals) {
215 bool thisItem = false;
216 foreach (PrincipalInfo opi in o.principals) {
217 if (((pi.Name == opi.Name) || (opi.Name == null)) &&
218 ((pi.Role == opi.Role) || (opi.Role == null)) &&
219 (pi.IsAuthenticated == opi.IsAuthenticated))
229 public bool IsUnrestricted ()
231 foreach (PrincipalInfo pi in principals) {
232 if ((pi.Name == null) && (pi.Role == null) && (pi.IsAuthenticated))
238 public override string ToString ()
240 return ToXml ().ToString ();
243 public SecurityElement ToXml ()
245 SecurityElement se = new SecurityElement ("IPermission");
246 Type type = this.GetType ();
247 StringBuilder asmName = new StringBuilder (type.Assembly.ToString ());
248 asmName.Replace ('\"', '\'');
249 se.AddAttribute ("class", type.FullName + ", " + asmName);
250 se.AddAttribute ("version", "1");
251 foreach (PrincipalInfo pi in principals) {
252 SecurityElement sec = new SecurityElement ("Identity");
254 sec.AddAttribute ("Name", pi.Name);
256 sec.AddAttribute ("Role", pi.Role);
257 if (pi.IsAuthenticated)
258 sec.AddAttribute ("Authenticated", "true");
264 public IPermission Union (IPermission target)
268 if (! (target is PrincipalPermission))
269 throw new ArgumentException ("wrong type");
271 PrincipalPermission o = (PrincipalPermission) target;
272 if (IsUnrestricted () || o.IsUnrestricted ())
273 return new PrincipalPermission (PermissionState.Unrestricted);
275 PrincipalPermission union = new PrincipalPermission (principals);
276 foreach (PrincipalInfo pi in o.principals)
277 union.principals.Add (pi);
282 // IBuiltInPermission
283 int IBuiltInPermission.GetTokenIndex ()