Merge pull request #4540 from kumpera/android-changes-part1
[mono.git] / mcs / class / System.IdentityModel / System.IdentityModel.Tokens / SamlAuthorizationDecisionStatement.cs
1 //
2 // SamlAuthorizationDecisionStatement.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc.  http://www.novell.com
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 using System;
29 using System.Collections.Generic;
30 using System.Xml;
31 using System.IdentityModel.Claims;
32 using System.IdentityModel.Policy;
33 using System.IdentityModel.Selectors;
34
35 namespace System.IdentityModel.Tokens
36 {
37         public class SamlAuthorizationDecisionStatement : SamlSubjectStatement
38         {
39                 public static string ClaimType {
40                         get { return "http://schemas.microsoft.com/mb/2005/09/ClaimType/SamlAuthorizationDecision"; }
41                 }
42
43                 public SamlAuthorizationDecisionStatement ()
44                 {
45                 }
46
47                 public SamlAuthorizationDecisionStatement (
48                         SamlSubject samlSubject, string resource,
49                         SamlAccessDecision accessDecision,
50                         IEnumerable<SamlAction> samlActions)
51                         : base (samlSubject)
52                 {
53                         if (samlActions == null)
54                                 throw new ArgumentNullException ("samlActions");
55                         if (resource == null || resource.Length == 0)
56                                 throw new SecurityTokenException ("non-zero length string must be set to Resource of SAML AuthorizationDecisionStatement.");
57                         Resource = resource;
58                         AccessDecision = accessDecision;
59                         foreach (SamlAction a in samlActions) {
60                                 if (a == null)
61                                         throw new ArgumentException ("samlActions contain null item.");
62                                 actions.Add (a);
63                         }
64                 }
65
66                 public SamlAuthorizationDecisionStatement (
67                         SamlSubject samlSubject, string resource,
68                         SamlAccessDecision accessDecision,
69                         IEnumerable<SamlAction> samlActions,
70                         SamlEvidence samlEvidence)
71                         : this (samlSubject, resource, accessDecision, samlActions)
72                 {
73                         evidence = samlEvidence;
74                 }
75
76                 SamlAccessDecision access_decision;
77                 SamlEvidence evidence;
78                 string resource;
79                 List<SamlAction> actions = new List<SamlAction> ();
80
81                 public IList<SamlAction> SamlActions {
82                         get { return actions; }
83                 }
84
85                 public SamlAccessDecision AccessDecision {
86                         get { return access_decision; }
87                         set {
88                                 CheckReadOnly ();
89                                 access_decision = value;
90                         }
91                 }
92
93                 public SamlEvidence Evidence {
94                         get { return evidence; }
95                         set {
96                                 CheckReadOnly ();
97                                 evidence = value;
98                         }
99                 }
100
101                 public string Resource {
102                         get { return resource; }
103                         set {
104                                 CheckReadOnly ();
105                                 if (value == null || value.Length == 0)
106                                         throw new ArgumentException ("non-zero length string must be set to Resource of SAML AuthorizationDecisionStatement.");
107                                 resource = value;
108                         }
109                 }
110
111                 public override bool IsReadOnly {
112                         get { return base.IsReadOnly; }
113                 }
114
115                 private void CheckReadOnly ()
116                 {
117                         if (IsReadOnly)
118                                 throw new InvalidOperationException ("This SAML assertion is read-only.");
119                 }
120
121                 public override void MakeReadOnly ()
122                 {
123                         base.MakeReadOnly ();
124                 }
125
126                 [MonoTODO]
127                 protected override void AddClaimsToList (IList<Claim> claims)
128                 {
129                         throw new NotImplementedException ();
130                 }
131
132                 public override void ReadXml (XmlDictionaryReader reader,
133                         SamlSerializer samlSerializer, 
134                         SecurityTokenSerializer keyInfoSerializer, 
135                         SecurityTokenResolver outOfBandTokenResolver)
136                 {
137                         if (reader == null)
138                                 throw new ArgumentNullException ("reader");
139                         if (samlSerializer == null)
140                                 throw new ArgumentNullException ("samlSerializer");
141
142                         string decision = reader.GetAttribute ("Decision");
143                         switch (decision) {
144                         case "Permit":
145                                 AccessDecision = SamlAccessDecision.Permit;
146                                 break;
147                         case "Deny":
148                                 AccessDecision = SamlAccessDecision.Deny;
149                                 break;
150                         case "Indeterminate":
151                                 AccessDecision = SamlAccessDecision.Indeterminate;
152                                 break;
153                         default:
154                                 throw new SecurityTokenException (String.Format ("AccessDecision value is wrong: {0}", decision));
155                         }
156                         Resource = reader.GetAttribute ("Resource");
157
158                         reader.ReadStartElement ("AuthorizationDecisionStatement", SamlConstants.Namespace);
159
160                         reader.MoveToContent ();
161                         SamlSubject = new SamlSubject ();
162                         SamlSubject.ReadXml (reader, samlSerializer, keyInfoSerializer, outOfBandTokenResolver);
163                         SamlActions.Clear ();
164                         for (reader.MoveToContent ();
165                              reader.LocalName == "Action" &&
166                              reader.NamespaceURI == SamlConstants.Namespace;
167                              reader.MoveToContent ()) {
168                                 SamlAction action = new SamlAction ();
169                                 action.ReadXml (reader, samlSerializer, keyInfoSerializer, outOfBandTokenResolver);
170                                 SamlActions.Add (action);
171                         }
172                         if (reader.LocalName == "Evidence" &&
173                             reader.NamespaceURI == SamlConstants.Namespace) {
174                                 Evidence = new SamlEvidence ();
175                                 Evidence.ReadXml (reader, samlSerializer, keyInfoSerializer, outOfBandTokenResolver);
176                                 reader.MoveToContent ();
177                         }
178                         reader.ReadEndElement ();
179
180                         // verify contents
181                         if (SamlActions.Count == 0)
182                                 throw new SecurityTokenException ("SAML AuthorizationDecisionStatement must contain at least one Action.");
183
184                         if (SamlSubject == null)
185                                 throw new SecurityTokenException ("SAML Subject must be set to SAML AuthorizationDecisionStatement before being written.");
186                         if (Resource == null || Resource.Length == 0)
187                                 throw new SecurityTokenException ("non-zero string must be set to Resource on SAML AuthorizationDecisionStatement.");
188                 }
189
190                 public override void WriteXml (XmlDictionaryWriter writer,
191                         SamlSerializer samlSerializer, 
192                         SecurityTokenSerializer keyInfoSerializer)
193                 {
194                         if (writer == null)
195                                 throw new ArgumentNullException ("writer");
196                         if (samlSerializer == null)
197                                 throw new ArgumentNullException ("samlSerializer");
198                         if (SamlActions.Count == 0)
199                                 throw new SecurityTokenException ("SAML AuthorizationDecisionStatement must contain at least one Action.");
200
201                         if (SamlSubject == null)
202                                 throw new SecurityTokenException ("SAML Subject must be set to SAML AuthorizationDecisionStatement before being written.");
203                         if (Resource == null || Resource.Length == 0)
204                                 throw new SecurityTokenException ("non-zero string must be set to Resource on SAML AuthorizationDecisionStatement.");
205
206                         writer.WriteStartElement ("saml", "AuthorizationDecisionStatement", SamlConstants.Namespace);
207
208                         writer.WriteStartAttribute ("Decision");
209                         switch (AccessDecision) {
210                         case SamlAccessDecision.Permit:
211                                 writer.WriteString ("Permit");
212                                 break;
213                         case SamlAccessDecision.Deny:
214                                 writer.WriteString ("Deny");
215                                 break;
216                         case SamlAccessDecision.Indeterminate:
217                                 writer.WriteString ("Indeterminate");
218                                 break;
219                         default:
220                                 throw new ArgumentOutOfRangeException ("AccessDecision value is wrong.");
221                         }
222                         writer.WriteEndAttribute ();
223
224                         writer.WriteAttributeString ("Resource", Resource);
225                         SamlSubject.WriteXml (writer, samlSerializer, keyInfoSerializer);
226                         foreach (SamlAction action in SamlActions)
227                                 action.WriteXml (writer, samlSerializer, keyInfoSerializer);
228                         if (Evidence != null)
229                                 Evidence.WriteXml (writer, samlSerializer, keyInfoSerializer);
230
231                         writer.WriteEndElement ();
232                 }
233         }
234 }