2004-01-26 Sebastien Pouliot <spouliot@videotron.ca>
[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 using System;
13 using System.Collections;
14 using System.Security.Permissions;
15 using System.Security;
16 using System.Runtime.Serialization;
17
18 namespace System.Security {
19
20         [Serializable]
21         public class PermissionSet: ISecurityEncodable, ICollection, IEnumerable, IStackWalk, IDeserializationCallback {
22
23                 private PermissionState state;
24                 private ArrayList list;
25
26                 // constructors
27
28                 // for PolicyLevel (to avoid validation duplication)
29                 internal PermissionSet () 
30                 {
31                         list = new ArrayList ();
32                 }
33
34                 public PermissionSet (PermissionState state)
35                 {
36                         if (!Enum.IsDefined(typeof(System.Security.Permissions.PermissionState), state))
37                                 throw new System.ArgumentException(); // state is not a valid System.Security.Permissions.PermissionState value.
38                         this.state = state;
39                         list = new ArrayList ();
40                 }
41
42                 public PermissionSet (PermissionSet permSet) : this (PermissionState.None)
43                 {
44                         // LAMESPEC: This would be handled by the compiler.  No way permSet is not a PermissionSet.
45                         //if (!(permSet is PermissionSet))
46                         //      throw new System.ArgumentException(); // permSet is not an instance of System.Security.PermissionSet.
47                         if (permSet == null)
48                                 state = PermissionState.Unrestricted;
49                         else {
50                                 foreach (IPermission p in permSet.list)
51                                         list.Add (p);
52                         }
53                 }
54
55                 // methods
56
57                 public virtual IPermission AddPermission (IPermission perm)
58                 {
59                         if (perm == null)
60                                 return null;
61
62                         IPermission existing = GetPermission (perm.GetType ());
63                         if (existing != null)
64                                 perm = perm.Union (existing);
65
66                         list.Add (perm);
67                         return perm;
68                 }
69
70                 [MonoTODO()]
71                 public virtual void Assert ()
72                 {
73                 }
74
75                 public virtual PermissionSet Copy ()
76                 {
77                         return new PermissionSet (this);
78                 }
79
80                 public virtual void CopyTo (Array array, int index)
81                 {
82                         if (array.Rank > 1)
83                                 throw new System.ArgumentException("Array has more than one dimension"); // array has more than one dimension.
84                         if (index < 0 || index >= array.Length)
85                                 throw new System.IndexOutOfRangeException(); // index is outside the range of allowable values for array.
86                         if (null == array)
87                                 throw new System.ArgumentNullException(); // array is null.
88                         list.CopyTo (array, index);
89                 }
90
91                 [MonoTODO()]
92                 public virtual void Demand ()
93                 {
94                 }
95
96                 [MonoTODO()]
97                 public virtual void Deny ()
98                 {
99                 }
100
101                 // to be re-used by NamedPermissionSet (and other derived classes)
102                 internal void FromXml (SecurityElement et, string className) 
103                 {
104                         if (et == null)
105                                 throw new ArgumentNullException ("et");
106                         if (et.Tag != "PermissionSet")
107                                 throw new ArgumentException ("not PermissionSet");
108                         if (!(et.Attributes ["class"] as string).EndsWith (className))
109                                 throw new ArgumentException ("not " + className);
110 // version isn't checked
111 //                      if ((et.Attributes ["version"] as string) != "1")
112 //                              throw new ArgumentException ("wrong version");
113
114                         if ((et.Attributes ["Unrestricted"] as string) == "true")
115                                 state = PermissionState.Unrestricted;
116                         else
117                                 state = PermissionState.None;
118                 }
119
120                 public virtual void FromXml (SecurityElement et)
121                 {
122                         list.Clear ();
123                         FromXml (et, "PermissionSet");
124                         if (et.Children != null) {
125                                 foreach (SecurityElement se in et.Children) {
126                                         string className = (se.Attributes ["class"] as string);
127                                         Type classType = Type.GetType (className);
128                                         object [] psNone = new object [1] { PermissionState.None };
129                                         IPermission p = (IPermission) Activator.CreateInstance (classType, psNone);
130                                         p.FromXml (se);
131                                         list.Add (p);
132                                 }
133                         }
134                 }
135
136                 public virtual IEnumerator GetEnumerator ()
137                 {
138                         return list.GetEnumerator ();
139                 }
140
141                 public virtual bool IsSubsetOf (PermissionSet target)
142                 {
143                         // if target is empty we must be empty too
144                         if ((target == null) || (target.IsEmpty ()))
145                                 return this.IsEmpty ();
146                         // if we're unrestricted then target must also be unrestricted
147                         if (this.IsUnrestricted () && target.IsUnrestricted ())
148                                 return true;
149
150                         // if each of our permission is (a) present and (b) a subset of target
151                         foreach (IPermission p in list) {
152                                 // for every type in both list
153                                 IPermission i = target.GetPermission (p.GetType ());
154                                 if (i == null)
155                                         return false; // not present (condition a)
156                                 if (!p.IsSubsetOf (i))
157                                         return false; // not a subset (condition b)
158                         }
159                         return true;
160                 }
161
162                 [MonoTODO()]
163                 public virtual void PermitOnly ()
164                 {
165                 }
166
167                 public bool ContainsNonCodeAccessPermissions () 
168                 {
169                         foreach (IPermission p in list) {
170                                 if (! p.GetType ().IsSubclassOf (typeof(CodeAccessPermission)))
171                                         return true;
172                         }
173                         return false;
174                 }
175
176                 // undocumented behavior
177                 [MonoTODO()]
178                 public static byte[] ConvertPermissionSet (string inFormat, byte[] inData, string outFormat) 
179                 {
180                         return null;
181                 }
182
183                 public virtual IPermission GetPermission (Type permClass) 
184                 {
185                         foreach (object o in list) {
186                                 if (o.GetType ().Equals (permClass))
187                                         return (IPermission) o;
188                         }
189                         return null;
190                 }
191
192                 public virtual PermissionSet Intersect (PermissionSet other) 
193                 {
194                         // no intersection possible
195                         if ((other == null) || (other.IsEmpty ()) || (this.IsEmpty ()))
196                                 return new PermissionSet (PermissionState.None);
197                         // intersections with unrestricted
198                         if (this.IsUnrestricted ())
199                                 return other.Copy ();
200                         if (other.IsUnrestricted ())
201                                 return this.Copy ();
202
203                         PermissionSet interSet = new PermissionSet (PermissionState.None);
204                         foreach (IPermission p in other.list) {
205                                 // for every type in both list
206                                 IPermission i = interSet.GetPermission (p.GetType ());
207                                 if (i != null) {
208                                         // add intersection for this type
209                                         interSet.AddPermission (p.Intersect (i));
210                                 }
211                                 // or reject!
212                         }
213                         return interSet;
214                 }
215
216                 public virtual bool IsEmpty () 
217                 {
218                         // note: Unrestricted isn't empty
219                         return ((state == PermissionState.Unrestricted) ? false : (list.Count == 0));
220                 }
221
222                 public virtual bool IsUnrestricted () 
223                 {
224                         return (state == PermissionState.Unrestricted);
225                 }
226
227                 public virtual IPermission RemovePermission (Type permClass) 
228                 {
229                         foreach (object o in list) {
230                                 if (o.GetType ().Equals (permClass)) {
231                                         list.Remove (o);
232                                         return (IPermission) o;
233                                 }
234                         }
235                         return null;
236                 }
237
238                 public virtual IPermission SetPermission (IPermission perm) 
239                 {
240                         if (perm is IUnrestrictedPermission)
241                                 state = PermissionState.None;
242                         RemovePermission (perm.GetType ());
243                         list.Add (perm);
244                         return perm;
245                 }
246
247                 public override string ToString ()
248                 {
249                         return ToXml ().ToString ();
250                 }
251
252                 public virtual SecurityElement ToXml ()
253                 {
254                         SecurityElement se = new SecurityElement ("PermissionSet");
255                         se.AddAttribute ("class", GetType ().FullName);
256                         se.AddAttribute ("version", "1");
257                         if (state == PermissionState.Unrestricted)
258                                 se.AddAttribute ("Unrestricted", "true");
259                         else {
260                                 foreach (IPermission p in list)
261                                         se.AddChild (p.ToXml ());
262                         }
263                         return se;
264                 }
265
266                 public virtual PermissionSet Union (PermissionSet other)
267                 {
268                         if (other == null)
269                                 return this.Copy ();
270                         if (this.IsUnrestricted () || other.IsUnrestricted ())
271                                 return new PermissionSet (PermissionState.Unrestricted);
272                         
273                         PermissionSet copy = this.Copy ();
274                         foreach (IPermission p in other.list) {
275                                 copy.AddPermission (p);
276                         }
277                         return copy;
278                 }
279
280                 public virtual int Count {
281                         get { return list.Count; }
282                 }
283
284                 public virtual bool IsSynchronized {
285                         get { return list.IsSynchronized; }
286                 }
287
288                 public virtual bool IsReadOnly {
289                         get { return false; } // always false
290                 }
291
292                 public virtual object SyncRoot {
293                         get { return list.SyncRoot; }
294                 }
295
296                 [MonoTODO()]
297                 void IDeserializationCallback.OnDeserialization (object sender) 
298                 {
299                 }
300         }
301 }