Merge pull request #1079 from esdrubal/webclient_cancel
[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                 string auth_type;
47
48                 public ClaimsIdentity ()
49                         : this (claims: null, authenticationType: null, nameType: null, roleType: null)
50                 { }
51                 
52                 public ClaimsIdentity (string authenticationType)
53                         : this (claims: null, authenticationType: authenticationType, nameType: null, roleType: null)
54                 { }
55
56                 public ClaimsIdentity (IEnumerable<Claim> claims, string authenticationType) 
57                         : this (claims, authenticationType, null, null)
58                 {}
59                 
60                 public ClaimsIdentity (string authenticationType, string nameType, string roleType)
61                         : this (claims: null, authenticationType: authenticationType, nameType: nameType, roleType: roleType)
62                 { }
63                 
64                 public ClaimsIdentity (IIdentity identity) : this (identity: identity, claims: null)
65                 {
66                 }
67                 
68                 public ClaimsIdentity(IEnumerable<Claim> claims, string authenticationType, string nameType, string roleType)
69                         : this (identity: null, claims: claims, authenticationType: authenticationType, nameType: nameType, roleType: roleType)
70                 {
71                         claims = claims == null ? new List<Claim> (): new List<Claim> (claims);
72                         
73                         // Special case: if empty, set to null.
74                         if (authenticationType == "")
75                                 auth_type = null;
76                         else
77                                 auth_type = authenticationType;
78
79                         NameClaimType = nameType == null ? DefaultNameClaimType : nameType;
80                         RoleClaimType = roleType == null ? DefaultRoleClaimType : roleType;
81                 }
82
83                 public ClaimsIdentity (IIdentity identity, IEnumerable<Claim> claims)
84                         : this (identity, claims, authenticationType: null, nameType: null, roleType: null)
85                 { }
86                 
87                 public ClaimsIdentity (IIdentity identity, IEnumerable<Claim> claims, string authenticationType, string nameType, string roleType)
88                 {
89                         var ci = identity as ClaimsIdentity;
90                         NameClaimType = nameType == null ? DefaultNameClaimType : nameType;
91                         RoleClaimType = roleType == null ? DefaultRoleClaimType : roleType;
92                         
93                         this.claims = new List<Claim> ();
94                         if (ci != null){
95                                 actor = ci.Actor;
96                                 BootstrapContext = ci.BootstrapContext;
97                                 foreach (var c in ci.Claims)
98                                         this.claims.Add (c);
99                                 
100                                 if (claims != null) {
101                                         foreach (var c in claims)
102                                                 this.claims.Add (c);
103                                 }
104                                 Label = ci.Label;
105                                 NameClaimType = ci.NameClaimType;
106                                 RoleClaimType = ci.RoleClaimType;
107                                 auth_type = ci.AuthenticationType;
108                         }
109                 }
110
111                 [MonoTODO]
112                 protected ClaimsIdentity (SerializationInfo info)
113                 {
114                         throw new NotImplementedException ();
115                 }
116
117                 [MonoTODO]
118                 protected ClaimsIdentity (SerializationInfo info, StreamingContext context)
119                 {
120                         if (info == null)
121                                 throw new ArgumentNullException ("info");
122                         throw new NotImplementedException ();
123                 }
124                 
125                 public ClaimsIdentity Actor {
126                         get {
127                                 return actor;
128                         }
129                         set {
130                                 if (actor == this)
131                                         throw new InvalidOperationException ("can not set the Actor property to this instance");
132                                 actor = value;
133                         }
134                 }
135
136                 public virtual string AuthenticationType {
137                         get {
138                                 return auth_type;
139                         }
140                 }
141                 public object BootstrapContext { get; set; }
142                 public string Label { get; set; }
143                 public virtual string Name {
144                         get {
145                                 var target = NameClaimType;
146                                 foreach (var c in claims){
147                                         if (c.Type == target)
148                                                 return c.Value;
149                                 }
150                                 return null;
151                         }
152                 }
153                 public string NameClaimType { get; private set; }
154                 public string RoleClaimType { get; private set; }
155
156                 public virtual IEnumerable<Claim> Claims {
157                         get {
158                                 return claims;
159                         }
160                 }
161
162                 public virtual bool IsAuthenticated {
163                         get {
164                                 return AuthenticationType != null && AuthenticationType != "";
165                         }
166                 }
167
168                 public virtual void AddClaim (Claim claim)
169                 {
170                         if (claim == null)
171                                 throw new ArgumentNullException ("claim");
172                         claims.Add (claim);
173                 }
174
175                 public virtual void AddClaims (IEnumerable<Claim> claims)
176                 {
177                         if (claims == null)
178                                 throw new ArgumentNullException ("claims");
179                         foreach (var c in claims)
180                                 this.claims.Add (c);
181                 }
182
183                 public virtual ClaimsIdentity Clone ()
184                 {
185                         return new ClaimsIdentity (null, claims, AuthenticationType, NameClaimType, RoleClaimType){
186                                 BootstrapContext = this.BootstrapContext,
187                                 Actor = this.Actor,
188                                 Label = this.Label
189                         };
190                 }
191
192                 public virtual IEnumerable<Claim> FindAll(Predicate<Claim> match)
193                 {
194                         if (match == null)
195                                 throw new ArgumentNullException ("match");
196                         foreach (var c in claims)
197                                 if (match (c))
198                                         yield return c;
199                 }
200
201                 public virtual IEnumerable<Claim> FindAll(string type)
202                 {
203                         if (type == null)
204                                 throw new ArgumentNullException ("type");
205                         foreach (var c in claims)
206                                 if (c.Type == type)
207                                         yield return c;
208                 }
209
210                 public virtual Claim FindFirst (Predicate<Claim> match)
211                 {
212                         if (match == null)
213                                 throw new ArgumentNullException ("match");
214                         foreach (var c in claims)
215                                 if (match (c))
216                                         return c;
217                         return null;
218                 }
219
220                 public virtual Claim FindFirst (string type)
221                 {
222                         if (type == null)
223                                 throw new ArgumentNullException ("type");
224                         foreach (var c in claims)
225                                 if (c.Type == type)
226                                         return c;
227                         return null;
228                 }
229
230                 public virtual bool HasClaim (Predicate<Claim> match)
231                 {
232                         if (match == null)
233                                 throw new ArgumentNullException ("match");
234                         foreach (var c in claims)
235                                 if (match (c))
236                                         return true;
237                         return false;
238                 }
239
240                 public virtual bool HasClaim (string type, string value)
241                 {
242                         if (type == null)
243                                 throw new ArgumentNullException ("type");
244                         if (value == null)
245                                 throw new ArgumentNullException ("value");
246                         foreach (var c in claims){
247                                 if (c.Type == type && c.Value == value)
248                                         return true;
249                         }
250                         return false;
251                 }
252
253                 public virtual void RemoveClaim (Claim claim)
254                 {
255                         if (!TryRemoveClaim (claim))
256                                 throw new InvalidOperationException ();
257                 }
258
259                 [MonoTODO ("This one should return false if the claim is owned by someone else, this does not exist yet")]
260                 public virtual bool TryRemoveClaim (Claim claim)
261                 {
262                         if (claim == null)
263                                 return true;
264                         claims.Remove (claim);
265                         return true;
266                 }
267         }
268 }
269 #endif