This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / class / corlib / System.Security / PermissionSet.cs
1 //
2 // System.Security.PermissionSet.cs
3 //
4 // Authors:
5 //      Nick Drochak(ndrochak@gol.com)
6 //      Sebastien Pouliot (spouliot@motus.com)
7 //
8 // (C) Nick Drochak
9 // Portions (C) 2003, 2004 Motus Technologies Inc. (http://www.motus.com)
10 //
11
12 //
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 //
36 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
37 //
38 // Permission is hereby granted, free of charge, to any person obtaining
39 // a copy of this software and associated documentation files (the
40 // "Software"), to deal in the Software without restriction, including
41 // without limitation the rights to use, copy, modify, merge, publish,
42 // distribute, sublicense, and/or sell copies of the Software, and to
43 // permit persons to whom the Software is furnished to do so, subject to
44 // the following conditions:
45 // 
46 // The above copyright notice and this permission notice shall be
47 // included in all copies or substantial portions of the Software.
48 // 
49 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
50 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
52 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
53 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
54 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
55 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56 //
57
58 using System;
59 using System.Collections;
60 using System.Security.Permissions;
61 using System.Security;
62 using System.Runtime.Serialization;
63
64 namespace System.Security {
65
66         [Serializable]
67         public class PermissionSet: ISecurityEncodable, ICollection, IEnumerable, IStackWalk, IDeserializationCallback {
68
69                 private PermissionState state;
70                 private ArrayList list;
71
72                 // constructors
73
74                 // for PolicyLevel (to avoid validation duplication)
75                 internal PermissionSet () 
76                 {
77                         list = new ArrayList ();
78                 }
79
80                 public PermissionSet (PermissionState state)
81                 {
82                         if (!Enum.IsDefined(typeof(System.Security.Permissions.PermissionState), state))
83                                 throw new System.ArgumentException(); // state is not a valid System.Security.Permissions.PermissionState value.
84                         this.state = state;
85                         list = new ArrayList ();
86                 }
87
88                 public PermissionSet (PermissionSet permSet) : this (PermissionState.None)
89                 {
90                         // LAMESPEC: This would be handled by the compiler.  No way permSet is not a PermissionSet.
91                         //if (!(permSet is PermissionSet))
92                         //      throw new System.ArgumentException(); // permSet is not an instance of System.Security.PermissionSet.
93                         if (permSet == null)
94                                 state = PermissionState.Unrestricted;
95                         else {
96                                 foreach (IPermission p in permSet.list)
97                                         list.Add (p);
98                         }
99                 }
100
101                 // methods
102
103                 public virtual IPermission AddPermission (IPermission perm)
104                 {
105                         if (perm == null)
106                                 return null;
107
108                         IPermission existing = GetPermission (perm.GetType ());
109                         if (existing != null)
110                                 perm = perm.Union (existing);
111
112                         list.Add (perm);
113                         return perm;
114                 }
115
116                 [MonoTODO()]
117                 public virtual void Assert ()
118                 {
119                 }
120
121                 public virtual PermissionSet Copy ()
122                 {
123                         return new PermissionSet (this);
124                 }
125
126                 public virtual void CopyTo (Array array, int index)
127                 {
128                         if (array.Rank > 1)
129                                 throw new System.ArgumentException("Array has more than one dimension"); // array has more than one dimension.
130                         if (index < 0 || index >= array.Length)
131                                 throw new System.IndexOutOfRangeException(); // index is outside the range of allowable values for array.
132                         if (null == array)
133                                 throw new System.ArgumentNullException(); // array is null.
134                         list.CopyTo (array, index);
135                 }
136
137                 [MonoTODO()]
138                 public virtual void Demand ()
139                 {
140                 }
141
142                 [MonoTODO()]
143                 public virtual void Deny ()
144                 {
145                 }
146
147                 // to be re-used by NamedPermissionSet (and other derived classes)
148                 internal void FromXml (SecurityElement et, string className) 
149                 {
150                         if (et == null)
151                                 throw new ArgumentNullException ("et");
152                         if (et.Tag != "PermissionSet")
153                                 throw new ArgumentException ("not PermissionSet");
154                         if (!(et.Attributes ["class"] as string).EndsWith (className))
155                                 throw new ArgumentException ("not " + className);
156 // version isn't checked
157 //                      if ((et.Attributes ["version"] as string) != "1")
158 //                              throw new ArgumentException ("wrong version");
159
160                         if ((et.Attributes ["Unrestricted"] as string) == "true")
161                                 state = PermissionState.Unrestricted;
162                         else
163                                 state = PermissionState.None;
164                 }
165
166                 public virtual void FromXml (SecurityElement et)
167                 {
168                         list.Clear ();
169                         FromXml (et, "PermissionSet");
170                         if (et.Children != null) {
171                                 foreach (SecurityElement se in et.Children) {
172                                         string className = (se.Attributes ["class"] as string);
173                                         Type classType = Type.GetType (className);
174                                         object [] psNone = new object [1] { PermissionState.None };
175                                         IPermission p = (IPermission) Activator.CreateInstance (classType, psNone);
176                                         p.FromXml (se);
177                                         list.Add (p);
178                                 }
179                         }
180                 }
181
182                 public virtual IEnumerator GetEnumerator ()
183                 {
184                         return list.GetEnumerator ();
185                 }
186
187                 public virtual bool IsSubsetOf (PermissionSet target)
188                 {
189                         // if target is empty we must be empty too
190                         if ((target == null) || (target.IsEmpty ()))
191                                 return this.IsEmpty ();
192                         // if we're unrestricted then target must also be unrestricted
193                         if (this.IsUnrestricted () && target.IsUnrestricted ())
194                                 return true;
195
196                         // if each of our permission is (a) present and (b) a subset of target
197                         foreach (IPermission p in list) {
198                                 // for every type in both list
199                                 IPermission i = target.GetPermission (p.GetType ());
200                                 if (i == null)
201                                         return false; // not present (condition a)
202                                 if (!p.IsSubsetOf (i))
203                                         return false; // not a subset (condition b)
204                         }
205                         return true;
206                 }
207
208                 [MonoTODO()]
209                 public virtual void PermitOnly ()
210                 {
211                 }
212
213                 public bool ContainsNonCodeAccessPermissions () 
214                 {
215                         foreach (IPermission p in list) {
216                                 if (! p.GetType ().IsSubclassOf (typeof(CodeAccessPermission)))
217                                         return true;
218                         }
219                         return false;
220                 }
221
222                 // undocumented behavior
223                 [MonoTODO()]
224                 public static byte[] ConvertPermissionSet (string inFormat, byte[] inData, string outFormat) 
225                 {
226                         return null;
227                 }
228
229                 public virtual IPermission GetPermission (Type permClass) 
230                 {
231                         foreach (object o in list) {
232                                 if (o.GetType ().Equals (permClass))
233                                         return (IPermission) o;
234                         }
235                         return null;
236                 }
237
238                 public virtual PermissionSet Intersect (PermissionSet other) 
239                 {
240                         // no intersection possible
241                         if ((other == null) || (other.IsEmpty ()) || (this.IsEmpty ()))
242                                 return new PermissionSet (PermissionState.None);
243                         // intersections with unrestricted
244                         if (this.IsUnrestricted ())
245                                 return other.Copy ();
246                         if (other.IsUnrestricted ())
247                                 return this.Copy ();
248
249                         PermissionSet interSet = new PermissionSet (PermissionState.None);
250                         foreach (IPermission p in other.list) {
251                                 // for every type in both list
252                                 IPermission i = interSet.GetPermission (p.GetType ());
253                                 if (i != null) {
254                                         // add intersection for this type
255                                         interSet.AddPermission (p.Intersect (i));
256                                 }
257                                 // or reject!
258                         }
259                         return interSet;
260                 }
261
262                 public virtual bool IsEmpty () 
263                 {
264                         // note: Unrestricted isn't empty
265                         return ((state == PermissionState.Unrestricted) ? false : (list.Count == 0));
266                 }
267
268                 public virtual bool IsUnrestricted () 
269                 {
270                         return (state == PermissionState.Unrestricted);
271                 }
272
273                 public virtual IPermission RemovePermission (Type permClass) 
274                 {
275                         foreach (object o in list) {
276                                 if (o.GetType ().Equals (permClass)) {
277                                         list.Remove (o);
278                                         return (IPermission) o;
279                                 }
280                         }
281                         return null;
282                 }
283
284                 public virtual IPermission SetPermission (IPermission perm) 
285                 {
286                         if (perm is IUnrestrictedPermission)
287                                 state = PermissionState.None;
288                         RemovePermission (perm.GetType ());
289                         list.Add (perm);
290                         return perm;
291                 }
292
293                 public override string ToString ()
294                 {
295                         return ToXml ().ToString ();
296                 }
297
298                 public virtual SecurityElement ToXml ()
299                 {
300                         SecurityElement se = new SecurityElement ("PermissionSet");
301                         se.AddAttribute ("class", GetType ().FullName);
302                         se.AddAttribute ("version", "1");
303                         if (state == PermissionState.Unrestricted)
304                                 se.AddAttribute ("Unrestricted", "true");
305                         else {
306                                 foreach (IPermission p in list)
307                                         se.AddChild (p.ToXml ());
308                         }
309                         return se;
310                 }
311
312                 public virtual PermissionSet Union (PermissionSet other)
313                 {
314                         if (other == null)
315                                 return this.Copy ();
316                         if (this.IsUnrestricted () || other.IsUnrestricted ())
317                                 return new PermissionSet (PermissionState.Unrestricted);
318                         
319                         PermissionSet copy = this.Copy ();
320                         foreach (IPermission p in other.list) {
321                                 copy.AddPermission (p);
322                         }
323                         return copy;
324                 }
325
326                 public virtual int Count {
327                         get { return list.Count; }
328                 }
329
330                 public virtual bool IsSynchronized {
331                         get { return list.IsSynchronized; }
332                 }
333
334                 public virtual bool IsReadOnly {
335                         get { return false; } // always false
336                 }
337
338                 public virtual object SyncRoot {
339                         get { return list.SyncRoot; }
340                 }
341
342                 [MonoTODO()]
343                 void IDeserializationCallback.OnDeserialization (object sender) 
344                 {
345                 }
346         }
347 }