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