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