Merge pull request #3528 from BrzVlad/fix-sgen-check-before-collections
[mono.git] / mcs / class / System.IdentityModel / Test / System.IdentityModel.Tokens / BootstrapContextTest.cs
1 //
2 // BootstrapContextTest.cs - NUnit Test Cases for System.IdentityModel.Tokens.BootstrapContext
3 //
4
5 using System;
6 using System.IO;
7 using System.IdentityModel.Tokens;
8 using System.Runtime.Serialization;
9 using System.Runtime.Serialization.Formatters.Binary;
10 using System.Text;
11 using System.Xml;
12 using NUnit.Framework;
13
14 namespace MonoTests.System.IdentityModel.Tokens.net_4_5 {
15         [TestFixture]
16         public class BootstrapContextTest {
17                 // The following byte arrays are the serialized bytes as emitted on Microsoft .Net 4.5.
18                 private static readonly byte [] SerializedBootstrapContextByteArray = new byte [] { 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x57, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, 0x3D, 0x6E, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6C, 0x2C, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x4B, 0x65, 0x79, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x3D, 0x62, 0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x05, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2E, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x73, 0x2E, 0x42, 0x6F, 0x6F, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x78, 0x74, 0x02, 0x00, 0x00, 0x00, 0x01, 0x4B, 0x01, 0x54, 0x00, 0x07, 0x03, 0x02, 0x02, 0x00, 0x00, 0x00, 0x42, 0x09, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x0B };
19                 private static readonly byte [] SerializedBootstrapContextString = new byte [] { 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x57, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, 0x3D, 0x6E, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6C, 0x2C, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x4B, 0x65, 0x79, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x3D, 0x62, 0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x05, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2E, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x73, 0x2E, 0x42, 0x6F, 0x6F, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x78, 0x74, 0x02, 0x00, 0x00, 0x00, 0x01, 0x4B, 0x01, 0x54, 0x00, 0x01, 0x03, 0x02, 0x00, 0x00, 0x00, 0x53, 0x06, 0x03, 0x00, 0x00, 0x00, 0x05, 0x74, 0x6F, 0x6B, 0x65, 0x6E, 0x0B };
20
21                 // Put in some non-ascii/latin1 characters to test the encoding scheme
22                 // \u018E == Latin capital letter Reversed E
23                 private const string user = "us\u018Er";
24                 // \u00BD == Vulgar Fraction one half
25                 private const string password = "pass\u00BDword";
26                 private static readonly string SerializedBootstrapContextSecurityTokenString = "<UserNameSecurityToken Id=\"uuid-927c0b98-ba18-49d2-a653-306d60f85751-3\" Username=\"" + user + "\" Password=\"" + password + "\"/>";
27                 private static readonly byte [] SerializedBootstrapContextSecurityToken = new byte [] { 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x57, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, 0x3D, 0x6E, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6C, 0x2C, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x4B, 0x65, 0x79, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x3D, 0x62, 0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x05, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2E, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x73, 0x2E, 0x42, 0x6F, 0x6F, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x78, 0x74, 0x02, 0x00, 0x00, 0x00, 0x01, 0x4B, 0x01, 0x54, 0x00, 0x01, 0x03, 0x02, 0x00, 0x00, 0x00, 0x54, 0x06, 0x03, 0x00, 0x00, 0x00, 0x98, 0x01, 0x50, 0x46, 0x56, 0x7A, 0x5A, 0x58, 0x4A, 0x4F, 0x59, 0x57, 0x31, 0x6C, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x70, 0x64, 0x48, 0x6C, 0x55, 0x62, 0x32, 0x74, 0x6C, 0x62, 0x69, 0x42, 0x4A, 0x5A, 0x44, 0x30, 0x69, 0x64, 0x58, 0x56, 0x70, 0x5A, 0x43, 0x30, 0x35, 0x4D, 0x6A, 0x64, 0x6A, 0x4D, 0x47, 0x49, 0x35, 0x4F, 0x43, 0x31, 0x69, 0x59, 0x54, 0x45, 0x34, 0x4C, 0x54, 0x51, 0x35, 0x5A, 0x44, 0x49, 0x74, 0x59, 0x54, 0x59, 0x31, 0x4D, 0x79, 0x30, 0x7A, 0x4D, 0x44, 0x5A, 0x6B, 0x4E, 0x6A, 0x42, 0x6D, 0x4F, 0x44, 0x55, 0x33, 0x4E, 0x54, 0x45, 0x74, 0x4D, 0x79, 0x49, 0x67, 0x56, 0x58, 0x4E, 0x6C, 0x63, 0x6D, 0x35, 0x68, 0x62, 0x57, 0x55, 0x39, 0x49, 0x6E, 0x56, 0x7A, 0x78, 0x6F, 0x35, 0x79, 0x49, 0x69, 0x42, 0x51, 0x59, 0x58, 0x4E, 0x7A, 0x64, 0x32, 0x39, 0x79, 0x5A, 0x44, 0x30, 0x69, 0x63, 0x47, 0x46, 0x7A, 0x63, 0x38, 0x4B, 0x39, 0x64, 0x32, 0x39, 0x79, 0x5A, 0x43, 0x49, 0x76, 0x50, 0x67, 0x3D, 0x3D, 0x0B };
28
29                 [Test]
30                 public void Ctor_StringToken_Works ()
31                 {
32                         BootstrapContext bootstrapContext = new BootstrapContext ("token");
33
34                         Assert.AreEqual ("token", bootstrapContext.Token, "#1");
35                         Assert.IsNull (bootstrapContext.TokenBytes, "#2");
36                         Assert.IsNull (bootstrapContext.SecurityToken, "#3");
37                         Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#4");
38                 }
39                 [Test]
40                 [ExpectedException (typeof (ArgumentNullException))]
41                 public void Ctor_StringToken_NullToken_Throws ()
42                 {
43                         BootstrapContext bootstrapContext = new BootstrapContext ((string)null);
44                         Assert.Fail ("Should have thrown");
45                 }
46
47                 [Test]
48                 public void Serialize_StringToken_Works ()
49                 {
50                         BootstrapContext bootstrapContext = new BootstrapContext ("token");
51                         BinaryFormatter binaryFormatter = new BinaryFormatter ();
52                         using (var s = new MemoryStream ()) {
53                                 binaryFormatter.Serialize (s, bootstrapContext);
54                                 s.Position = 0;
55                                 BootstrapContext bootstrapContext2 = binaryFormatter.Deserialize (s) as BootstrapContext;
56                                 Assert.IsNotNull (bootstrapContext2, "#1");
57                                 Assert.AreEqual (bootstrapContext.Token, bootstrapContext2.Token, "#2");
58                                 Assert.AreEqual (bootstrapContext.TokenBytes, bootstrapContext2.TokenBytes, "#3");
59                                 Assert.AreEqual (bootstrapContext.SecurityToken, bootstrapContext2.SecurityToken, "#4");
60                                 Assert.AreEqual (bootstrapContext.SecurityTokenHandler, bootstrapContext2.SecurityTokenHandler, "#5");
61                         }
62                 }
63
64                 [Test]
65                 public void Deserialize_StringToken_Works ()
66                 {
67                         BinaryFormatter binaryFormatter = new BinaryFormatter ();
68                         using (var s = new MemoryStream (SerializedBootstrapContextString)) {
69                                 BootstrapContext bootstrapContext = binaryFormatter.Deserialize (s) as BootstrapContext;
70                                 Assert.IsNotNull (bootstrapContext, "#1");
71                                 Assert.AreEqual ("token", bootstrapContext.Token, "#2");
72                                 Assert.IsNull (bootstrapContext.TokenBytes, "#3");
73                                 Assert.IsNull (bootstrapContext.SecurityToken, "#4");
74                                 Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#5");
75                         }
76                 }
77
78                 [Test]
79                 public void Ctor_ByteArrayToken_Works ()
80                 {
81                         BootstrapContext bootstrapContext = new BootstrapContext (new byte [] { 0x01 });
82
83                         Assert.IsNotNull (bootstrapContext.TokenBytes, "#1");
84                         Assert.AreEqual (1, bootstrapContext.TokenBytes.Length, "#2");
85                         Assert.AreEqual (1, bootstrapContext.TokenBytes [0], "#3");
86                         Assert.IsNull (bootstrapContext.Token, "#4");
87                         Assert.IsNull (bootstrapContext.SecurityToken, "#5");
88                         Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#6");
89                 }
90
91                 [Test]
92                 [ExpectedException (typeof (ArgumentNullException))]
93                 public void Ctor_ByteArrayToken_NullToken_Throws ()
94                 {
95                         BootstrapContext bootstrapContext = new BootstrapContext ((byte [])null);
96                         Assert.Fail ("Should have thrown");
97                 }
98
99                 [Test]
100                 public void Serialize_ByteArrayToken_Works ()
101                 {
102                         BootstrapContext bootstrapContext = new BootstrapContext (new byte [] { 0x1 });
103                         BinaryFormatter binaryFormatter = new BinaryFormatter ();
104                         using (var s = new MemoryStream ()) {
105                                 binaryFormatter.Serialize (s, bootstrapContext);
106                                 s.Position = 0;
107                                 BootstrapContext bootstrapContext2 = binaryFormatter.Deserialize (s) as BootstrapContext;
108                                 Assert.IsNotNull (bootstrapContext2, "#1");
109                                 Assert.AreEqual (bootstrapContext.Token, bootstrapContext2.Token, "#2");
110                                 Assert.AreEqual (bootstrapContext.TokenBytes, bootstrapContext2.TokenBytes, "#3");
111                                 Assert.AreEqual (bootstrapContext.SecurityToken, bootstrapContext2.SecurityToken, "#4");
112                                 Assert.AreEqual (bootstrapContext.SecurityTokenHandler, bootstrapContext2.SecurityTokenHandler, "#5");
113                         }
114                 }
115
116                 [Test]
117                 public void Deserialize_ByteArrayToken_Works ()
118                 {
119                         BinaryFormatter binaryFormatter = new BinaryFormatter ();
120                         using (var s = new MemoryStream (SerializedBootstrapContextByteArray)) {
121                                 BootstrapContext bootstrapContext = binaryFormatter.Deserialize (s) as BootstrapContext;
122                                 Assert.IsNotNull (bootstrapContext, "#1");
123                                 Assert.IsNotNull (bootstrapContext.TokenBytes, "#2");
124                                 Assert.AreEqual (1, bootstrapContext.TokenBytes.Length, "#3");
125                                 Assert.AreEqual (1, bootstrapContext.TokenBytes [0], "#4");
126                                 Assert.IsNull (bootstrapContext.Token, "#5");
127                                 Assert.IsNull (bootstrapContext.SecurityToken, "#6");
128                                 Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#7");
129                         }
130                 }
131
132                 [Test]
133                 public void Ctor_SecurityToken_Works ()
134                 {
135                         var securityToken = new UserNameSecurityToken (user, password);
136                         var securityTokenHandler = new SimpleSecurityTokenHandler ();
137                         BootstrapContext bootstrapContext = new BootstrapContext (securityToken, securityTokenHandler);
138
139                         Assert.IsNotNull (bootstrapContext.SecurityToken, "#1");
140                         Assert.AreEqual (user, securityToken.UserName, "#2");
141                         Assert.AreEqual (password, securityToken.Password, "#3");
142                         Assert.AreEqual (securityTokenHandler, bootstrapContext.SecurityTokenHandler, "#4");
143
144                         Assert.IsNull (bootstrapContext.Token, "#5");
145                         Assert.IsNull (bootstrapContext.TokenBytes, "#6");
146                 }
147
148                 [Test]
149                 [ExpectedException (typeof (ArgumentNullException))]
150                 public void Ctor_SecurityToken_NullToken_Throws ()
151                 {
152                         BootstrapContext bootstrapContext = new BootstrapContext (null, new SimpleSecurityTokenHandler ());
153                         Assert.Fail ("Should have thrown");
154                 }
155
156                 [Test]
157                 [ExpectedException (typeof (ArgumentNullException))]
158                 public void Ctor_SecurityToken_NullHandler_Throws ()
159                 {
160                         BootstrapContext bootstrapContext = new BootstrapContext (new UserNameSecurityToken ("user", "password"), null);
161                         Assert.Fail ("Should have thrown");
162                 }
163
164                 [Test]
165                 public void Serialize_SecurityTokenAndHandler_Works ()
166                 {
167                         var securityToken = new UserNameSecurityToken (user, password, "uuid-927c0b98-ba18-49d2-a653-306d60f85751-3");
168                         var securityTokenHandler = new SimpleSecurityTokenHandler ();
169                         BootstrapContext bootstrapContext = new BootstrapContext (securityToken, securityTokenHandler);
170
171                         BinaryFormatter binaryFormatter = new BinaryFormatter ();
172                         using (var s = new MemoryStream ()) {
173                                 binaryFormatter.Serialize (s, bootstrapContext);
174                                 s.Position = 0;
175                                 BootstrapContext bootstrapContext2 = binaryFormatter.Deserialize (s) as BootstrapContext;
176                                 Assert.IsNotNull (bootstrapContext2, "#1");
177                                 // Deserialize does not restore the SecurityToken, but restores into the Token.
178                                 Assert.IsNotNull (bootstrapContext2.Token, "#3");
179                                 // We replace ' /' by '/' to accomodate the xml writer differences between mono and .net
180                                 Assert.AreEqual (SerializedBootstrapContextSecurityTokenString.Replace (" /", "/"), bootstrapContext2.Token.Replace (" /", "/"), "#2");
181                                 Assert.AreEqual (bootstrapContext.TokenBytes, bootstrapContext2.TokenBytes, "#3");
182                                 Assert.IsNull (bootstrapContext2.SecurityToken, "#4");
183                                 Assert.IsNull (bootstrapContext2.SecurityTokenHandler, "#5");
184                         }
185                 }
186
187                 [Test]
188                 public void Deserialize_SecurityTokenAndHandler_Works ()
189                 {
190                         BinaryFormatter binaryFormatter = new BinaryFormatter ();
191                         using (var s = new MemoryStream (SerializedBootstrapContextSecurityToken)) {
192                                 BootstrapContext bootstrapContext = binaryFormatter.Deserialize (s) as BootstrapContext;
193                                 Assert.IsNotNull (bootstrapContext, "#1");
194                                 Assert.AreEqual (SerializedBootstrapContextSecurityTokenString, bootstrapContext.Token, "#2");
195                                 Assert.IsNull (bootstrapContext.SecurityToken, "#3");
196                                 Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#4");
197                                 Assert.IsNull (bootstrapContext.TokenBytes, "#5");
198                         }
199                 }
200
201                 private static void DumpAsText (byte [] data)
202                 {
203                         Console.WriteLine ("{0}", Encoding.ASCII.GetString (data));
204                 }
205
206                 private static void Dump (byte [] data)
207                 {
208                         var sb = new StringBuilder ();
209                         sb.Append ("new byte[] { ");
210                         bool first = true;
211                         foreach (byte b in data) {
212                                 if (!first)
213                                         sb.Append (", ");
214                                 else
215                                         first = false;
216                                 sb.AppendFormat ("0x{0:X2}", b);
217                         }
218                         sb.Append (" };");
219                         Console.WriteLine (sb.ToString ());
220                 }
221
222                 private class SimpleSecurityTokenHandler : SecurityTokenHandler {
223                         public override string [] GetTokenTypeIdentifiers ()
224                         {
225                                 throw new NotImplementedException ();
226                         }
227
228                         public override Type TokenType {
229                                 get { return typeof (UserNameSecurityToken); }
230                         }
231
232                         public override bool CanWriteToken {
233                                 get { return true; }
234                         }
235
236                         public override void WriteToken (XmlWriter writer, SecurityToken token)
237                         {
238                                 UserNameSecurityToken unst = token as UserNameSecurityToken;
239                                 if (unst == null)
240                                         throw new ArgumentException ("Token must be of type UserNameSecurityToken", "token");
241                                 writer.WriteStartElement ("UserNameSecurityToken");
242                                 writer.WriteAttributeString ("Id", unst.Id);
243                                 writer.WriteAttributeString ("Username", unst.UserName);
244                                 writer.WriteAttributeString ("Password", unst.Password);
245                                 writer.WriteEndElement ();
246                         }
247                 }
248         }
249 }