Overwrites dequeued ref/value with default. Fixes 18421.
[mono.git] / mcs / class / corlib / System.Security.Claims / ClaimsIdentity.cs
1 //
2 // ClaimIdentity.cs
3 //
4 // Authors:
5 //  Miguel de Icaza (miguel@xamarin.com)
6 //
7 // Copyright 2014 Xamarin Inc
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 #if NET_4_5
29 using System;
30 using System.Collections.Generic;
31 using System.Security.Principal;
32 using System.Runtime.Serialization;
33 namespace System.Security.Claims {
34
35         [Serializable]
36         public class ClaimsIdentity : IIdentity {
37                 [NonSerializedAttribute]
38                 public const string DefaultNameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name";
39                 [NonSerializedAttribute]
40                 public const string DefaultRoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
41                 [NonSerializedAttribute]
42                 public const string DefaultIssuer = "LOCAL AUTHORITY";
43                 
44                 List<Claim> claims;
45                 ClaimsIdentity actor;
46
47                 public ClaimsIdentity ()
48                         : this (claims: null, authenticationType: null, nameType: null, roleType: null)
49                 { }
50                 
51                 public ClaimsIdentity (string authenticationType)
52                         : this (claims: null, authenticationType: authenticationType, nameType: null, roleType: null)
53                 { }
54
55                 public ClaimsIdentity (IEnumerable<Claim> claims, string authenticationType) 
56                         : this (claims, authenticationType, null, null)
57                 {}
58                 
59                 public ClaimsIdentity (string authenticationType, string nameType, string roleType)
60                         : this (claims: null, authenticationType: authenticationType, nameType: nameType, roleType: roleType)
61                 { }
62                 
63                 public ClaimsIdentity (IIdentity identity) : this (identity: identity, claims: null)
64                 {
65                 }
66                 
67                 public ClaimsIdentity(IEnumerable<Claim> claims, string authenticationType, string nameType, string roleType)
68                         : this (identity: null, claims: claims, authenticationType: authenticationType, nameType: nameType, roleType: roleType)
69                 {
70                         claims = claims == null ? new List<Claim> (): new List<Claim> (claims);
71                         
72                         AuthenticationType = authenticationType;
73
74                         // Special case: if empty, set to null.
75                         if (authenticationType == "")
76                                 AuthenticationType = null;
77                         
78                         NameClaimType = nameType == null ? DefaultNameClaimType : nameType;
79                         RoleClaimType = roleType == null ? DefaultRoleClaimType : roleType;
80                 }
81
82                 public ClaimsIdentity (IIdentity identity, IEnumerable<Claim> claims)
83                         : this (identity, claims, authenticationType: null, nameType: null, roleType: null)
84                 { }
85                 
86                 public ClaimsIdentity (IIdentity identity, IEnumerable<Claim> claims, string authenticationType, string nameType, string roleType)
87                 {
88                         var ci = identity as ClaimsIdentity;
89                         NameClaimType = nameType == null ? DefaultNameClaimType : nameType;
90                         RoleClaimType = roleType == null ? DefaultRoleClaimType : roleType;
91                         
92                         this.claims = new List<Claim> ();
93                         if (ci != null){
94                                 actor = ci.Actor;
95                                 BootstrapContext = ci.BootstrapContext;
96                                 foreach (var c in ci.Claims)
97                                         this.claims.Add (c);
98                                 
99                                 foreach (var c in claims)
100                                         this.claims.Add (c);
101                                 Label = ci.Label;
102                                 NameClaimType = ci.NameClaimType;
103                                 RoleClaimType = ci.RoleClaimType;
104                                 AuthenticationType = ci.AuthenticationType;
105                         }
106                 }
107
108                 [MonoTODO]
109                 protected ClaimsIdentity (SerializationInfo info)
110                 {
111                         throw new NotImplementedException ();
112                 }
113
114                 [MonoTODO]
115                 protected ClaimsIdentity (SerializationInfo info, StreamingContext context)
116                 {
117                         if (info == null)
118                                 throw new ArgumentNullException ("info");
119                         throw new NotImplementedException ();
120                 }
121                 
122                 public ClaimsIdentity Actor {
123                         get {
124                                 return actor;
125                         }
126                         set {
127                                 if (actor == this)
128                                         throw new InvalidOperationException ("can not set the Actor property to this instance");
129                                 actor = value;
130                         }
131                 }
132
133                 public virtual string AuthenticationType { get; private set; }
134                 public object BootstrapContext { get; set; }
135                 public string Label { get; set; }
136                 public virtual string Name {
137                         get {
138                                 var target = NameClaimType;
139                                 foreach (var c in claims){
140                                         if (c.Type == target)
141                                                 return c.Value;
142                                 }
143                                 return null;
144                         }
145                 }
146                 public string NameClaimType { get; private set; }
147                 public string RoleClaimType { get; private set; }
148
149                 public virtual IEnumerable<Claim> Claims {
150                         get {
151                                 return claims;
152                         }
153                 }
154
155                 public virtual bool IsAuthenticated {
156                         get {
157                                 return AuthenticationType != null && AuthenticationType != "";
158                         }
159                 }
160
161                 public virtual void AddClaim (Claim claim)
162                 {
163                         if (claim == null)
164                                 throw new ArgumentNullException ("claim");
165                         claims.Add (claim);
166                 }
167
168                 public virtual void AddClaims (IEnumerable<Claim> claims)
169                 {
170                         if (claims == null)
171                                 throw new ArgumentNullException ("claims");
172                         foreach (var c in claims)
173                                 this.claims.Add (c);
174                 }
175
176                 public virtual ClaimsIdentity Clone ()
177                 {
178                         return new ClaimsIdentity (null, claims, AuthenticationType, NameClaimType, RoleClaimType){
179                                 BootstrapContext = this.BootstrapContext,
180                                 Actor = this.Actor,
181                                 Label = this.Label
182                         };
183                 }
184
185                 public virtual IEnumerable<Claim> FindAll(Predicate<Claim> match)
186                 {
187                         if (match == null)
188                                 throw new ArgumentNullException ("match");
189                         foreach (var c in claims)
190                                 if (match (c))
191                                         yield return c;
192                 }
193
194                 public virtual IEnumerable<Claim> FindAll(string type)
195                 {
196                         if (type == null)
197                                 throw new ArgumentNullException ("type");
198                         foreach (var c in claims)
199                                 if (c.Type == type)
200                                         yield return c;
201                 }
202
203                 public virtual Claim FindFirst (Predicate<Claim> match)
204                 {
205                         if (match == null)
206                                 throw new ArgumentNullException ("match");
207                         foreach (var c in claims)
208                                 if (match (c))
209                                         return c;
210                         return null;
211                 }
212
213                 public virtual Claim FindFirst (string type)
214                 {
215                         if (type == null)
216                                 throw new ArgumentNullException ("type");
217                         foreach (var c in claims)
218                                 if (c.Type == type)
219                                         return c;
220                         return null;
221                 }
222
223                 public virtual bool HasClaim (Predicate<Claim> match)
224                 {
225                         if (match == null)
226                                 throw new ArgumentNullException ("match");
227                         foreach (var c in claims)
228                                 if (match (c))
229                                         return true;
230                         return false;
231                 }
232
233                 public virtual bool HasClaim (string type, string value)
234                 {
235                         if (type == null)
236                                 throw new ArgumentNullException ("type");
237                         if (value == null)
238                                 throw new ArgumentNullException ("value");
239                         foreach (var c in claims){
240                                 if (c.Type == type && c.Value == value)
241                                         return true;
242                         }
243                         return false;
244                 }
245
246                 public virtual void RemoveClaim (Claim claim)
247                 {
248                         if (!TryRemoveClaim (claim))
249                                 throw new InvalidOperationException ();
250                 }
251
252                 [MonoTODO ("This one should return false if the claim is owned by someone else, this does not exist yet")]
253                 public virtual bool TryRemoveClaim (Claim claim)
254                 {
255                         if (claim == null)
256                                 return true;
257                         claims.Remove (claim);
258                         return true;
259                 }
260         }
261 }
262 #endif