Bug Fix #98 Ensure Usernames are not case-sensitive

This commit is contained in:
Gary Sharp
2016-11-03 17:12:50 +11:00
parent 6df2e16a7f
commit c72c18e825
9 changed files with 52 additions and 60 deletions
+8 -13
View File
@@ -3,16 +3,13 @@ using Disco.Models.Repository;
using Disco.Services.Authorization; using Disco.Services.Authorization;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Disco.Services.Users namespace Disco.Services.Users
{ {
internal static class Cache internal static class Cache
{ {
private static ConcurrentDictionary<string, Tuple<User, AuthorizationToken, DateTime>> _Cache = new ConcurrentDictionary<string, Tuple<User, AuthorizationToken, DateTime>>(); private static ConcurrentDictionary<string, Tuple<User, AuthorizationToken, DateTime>> _Cache = new ConcurrentDictionary<string, Tuple<User, AuthorizationToken, DateTime>>(StringComparer.OrdinalIgnoreCase);
private const long CacheTimeoutTicks = 6000000000; // 10 Minutes private const long CacheTimeoutTicks = 6000000000; // 10 Minutes
internal static AuthorizationToken GetAuthorization(string UserId, DiscoDataContext Database, bool ForceRefresh) internal static AuthorizationToken GetAuthorization(string UserId, DiscoDataContext Database, bool ForceRefresh)
@@ -116,14 +113,13 @@ namespace Disco.Services.Users
{ {
var cache = _Cache; var cache = _Cache;
string userId = UserId.ToLower();
Tuple<User, AuthorizationToken, DateTime> record; Tuple<User, AuthorizationToken, DateTime> record;
if (cache.TryGetValue(userId, out record)) if (cache.TryGetValue(UserId, out record))
{ {
if (record.Item3 > DateTime.Now) if (record.Item3 > DateTime.Now)
return record; return record;
else else
cache.TryRemove(userId, out record); cache.TryRemove(UserId, out record);
} }
return null; return null;
} }
@@ -132,18 +128,17 @@ namespace Disco.Services.Users
{ {
var cache = _Cache; var cache = _Cache;
string userId = UserId.ToLower();
Tuple<User, AuthorizationToken, DateTime> record = new Tuple<User, AuthorizationToken, DateTime>(Record.Item1, Record.Item2, DateTime.Now.AddTicks(CacheTimeoutTicks)); Tuple<User, AuthorizationToken, DateTime> record = new Tuple<User, AuthorizationToken, DateTime>(Record.Item1, Record.Item2, DateTime.Now.AddTicks(CacheTimeoutTicks));
if (cache.ContainsKey(userId)) if (cache.ContainsKey(UserId))
{ {
Tuple<User, AuthorizationToken, DateTime> oldRecord; Tuple<User, AuthorizationToken, DateTime> oldRecord;
if (cache.TryGetValue(userId, out oldRecord)) if (cache.TryGetValue(UserId, out oldRecord))
{ {
cache.TryUpdate(userId, record, oldRecord); cache.TryUpdate(UserId, record, oldRecord);
return record; return record;
} }
} }
cache.TryAdd(userId, record); cache.TryAdd(UserId, record);
return record; return record;
} }
@@ -170,7 +165,7 @@ namespace Disco.Services.Users
} }
internal static void FlushCache() internal static void FlushCache()
{ {
_Cache = new ConcurrentDictionary<string, Tuple<User, AuthorizationToken, DateTime>>(); _Cache = new ConcurrentDictionary<string, Tuple<User, AuthorizationToken, DateTime>>(StringComparer.OrdinalIgnoreCase);
} }
} }
} }
@@ -493,7 +493,7 @@ namespace Disco.Web.Areas.API.Controllers
var da = new DeviceAttachment() var da = new DeviceAttachment()
{ {
DeviceSerialNumber = d.SerialNumber, DeviceSerialNumber = d.SerialNumber,
TechUserId = UserService.CurrentUser.UserId, TechUserId = CurrentUser.UserId,
Filename = file.FileName, Filename = file.FileName,
MimeType = contentType, MimeType = contentType,
Timestamp = DateTime.Now, Timestamp = DateTime.Now,
@@ -78,7 +78,7 @@ namespace Disco.Web.Areas.API.Controllers
var ua = new Disco.Models.Repository.UserAttachment() var ua = new Disco.Models.Repository.UserAttachment()
{ {
UserId = u.UserId, UserId = u.UserId,
TechUserId = UserService.CurrentUser.UserId, TechUserId = CurrentUser.UserId,
Filename = file.FileName, Filename = file.FileName,
MimeType = contentType, MimeType = contentType,
Timestamp = DateTime.Now, Timestamp = DateTime.Now,
@@ -36,7 +36,7 @@
{ @da.DocumentTemplate.Description} { @da.DocumentTemplate.Description}
else else
{ @da.Comments }} { @da.Comments }}
</span><span class="author">@da.TechUser.ToString()</span>@if (canRemoveAnyAttachments || (canRemoveOwnAttachments && da.TechUserId == CurrentUser.UserId)) </span><span class="author">@da.TechUser.ToString()</span>@if (canRemoveAnyAttachments || (canRemoveOwnAttachments && da.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
{<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" title="@da.Timestamp.ToFullDateTime()" data-livestamp="@da.Timestamp.ToUnixEpoc()">@da.Timestamp.ToFullDateTime()</span> {<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" title="@da.Timestamp.ToFullDateTime()" data-livestamp="@da.Timestamp.ToUnixEpoc()">@da.Timestamp.ToFullDateTime()</span>
</a> </a>
} }
@@ -2,7 +2,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Runtime Version:4.0.30319.34014 // Runtime Version:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -27,7 +27,6 @@ namespace Disco.Web.Views.Device.DeviceParts
using System.Web.UI; using System.Web.UI;
using System.Web.WebPages; using System.Web.WebPages;
using Disco; using Disco;
using Disco.BI.Extensions;
using Disco.Models.Repository; using Disco.Models.Repository;
using Disco.Services; using Disco.Services;
using Disco.Services.Authorization; using Disco.Services.Authorization;
@@ -37,9 +36,9 @@ namespace Disco.Web.Views.Device.DeviceParts
[System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "2.0.0.0")] [System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "2.0.0.0")]
[System.Web.WebPages.PageVirtualPathAttribute("~/Views/Device/DeviceParts/_Resources.cshtml")] [System.Web.WebPages.PageVirtualPathAttribute("~/Views/Device/DeviceParts/_Resources.cshtml")]
public partial class Resources : Disco.Services.Web.WebViewPage<Disco.Web.Models.Device.ShowModel> public partial class _Resources : Disco.Services.Web.WebViewPage<Disco.Web.Models.Device.ShowModel>
{ {
public Resources() public _Resources()
{ {
} }
public override void Execute() public override void Execute()
@@ -256,7 +255,7 @@ WriteLiteral("</span>");
#line 39 "..\..\Views\Device\DeviceParts\_Resources.cshtml" #line 39 "..\..\Views\Device\DeviceParts\_Resources.cshtml"
if (canRemoveAnyAttachments || (canRemoveOwnAttachments && da.TechUserId == CurrentUser.UserId)) if (canRemoveAnyAttachments || (canRemoveOwnAttachments && da.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
{ {
#line default #line default
@@ -277,14 +276,14 @@ WriteLiteral("<span");
WriteLiteral(" class=\"timestamp\""); WriteLiteral(" class=\"timestamp\"");
WriteAttribute("title", Tuple.Create(" title=\"", 2453), Tuple.Create("\"", 2491) WriteAttribute("title", Tuple.Create(" title=\"", 2494), Tuple.Create("\"", 2532)
#line 40 "..\..\Views\Device\DeviceParts\_Resources.cshtml" #line 40 "..\..\Views\Device\DeviceParts\_Resources.cshtml"
, Tuple.Create(Tuple.Create("", 2461), Tuple.Create<System.Object, System.Int32>(da.Timestamp.ToFullDateTime() , Tuple.Create(Tuple.Create("", 2502), Tuple.Create<System.Object, System.Int32>(da.Timestamp.ToFullDateTime()
#line default #line default
#line hidden #line hidden
, 2461), false) , 2502), false)
); );
WriteLiteral(" data-livestamp=\""); WriteLiteral(" data-livestamp=\"");
@@ -34,7 +34,7 @@
@foreach (var jl in Model.Job.JobLogs.OrderBy(m => m.Timestamp)) @foreach (var jl in Model.Job.JobLogs.OrderBy(m => m.Timestamp))
{ {
<div data-logid="@jl.Id"> <div data-logid="@jl.Id">
<span class="author">@jl.TechUser.ToStringFriendly()</span>@if (canRemoveAnyLogs || (canRemoveOwnLogs && jl.TechUserId == CurrentUser.UserId)) <span class="author">@jl.TechUser.ToStringFriendly()</span>@if (canRemoveAnyLogs || (canRemoveOwnLogs && jl.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
{<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" data-livestamp="@(jl.Timestamp.ToUnixEpoc())" title="@jl.Timestamp.ToFullDateTime()">@jl.Timestamp.ToFullDateTime()</span> {<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" data-livestamp="@(jl.Timestamp.ToUnixEpoc())" title="@jl.Timestamp.ToFullDateTime()">@jl.Timestamp.ToFullDateTime()</span>
<div class="comment">@jl.Comments.ToHtmlComment()</div> <div class="comment">@jl.Comments.ToHtmlComment()</div>
</div> </div>
@@ -68,7 +68,7 @@
{ @ja.DocumentTemplate.Description} { @ja.DocumentTemplate.Description}
else else
{ @ja.Comments }} { @ja.Comments }}
</span><span class="author">@ja.TechUser.ToStringFriendly()</span>@if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ja.TechUserId == CurrentUser.UserId)) </span><span class="author">@ja.TechUser.ToStringFriendly()</span>@if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ja.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
{<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" data-livestamp="@(ja.Timestamp.ToUnixEpoc())" title="@ja.Timestamp.ToFullDateTime()">@ja.Timestamp.ToFullDateTime()</span> {<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" data-livestamp="@(ja.Timestamp.ToUnixEpoc())" title="@ja.Timestamp.ToFullDateTime()">@ja.Timestamp.ToFullDateTime()</span>
</a> </a>
} }
@@ -2,7 +2,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Runtime Version:4.0.30319.34014 // Runtime Version:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -27,7 +27,6 @@ namespace Disco.Web.Views.Job.JobParts
using System.Web.UI; using System.Web.UI;
using System.Web.WebPages; using System.Web.WebPages;
using Disco; using Disco;
using Disco.BI.Extensions;
using Disco.Models.Repository; using Disco.Models.Repository;
using Disco.Services; using Disco.Services;
using Disco.Services.Authorization; using Disco.Services.Authorization;
@@ -181,7 +180,7 @@ WriteLiteral("</span>");
#line 37 "..\..\Views\Job\JobParts\Resources.cshtml" #line 37 "..\..\Views\Job\JobParts\Resources.cshtml"
if (canRemoveAnyLogs || (canRemoveOwnLogs && jl.TechUserId == CurrentUser.UserId)) if (canRemoveAnyLogs || (canRemoveOwnLogs && jl.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
{ {
#line default #line default
@@ -213,14 +212,14 @@ WriteLiteral(" data-livestamp=\"");
#line hidden #line hidden
WriteLiteral("\""); WriteLiteral("\"");
WriteAttribute("title", Tuple.Create(" title=\"", 2091), Tuple.Create("\"", 2129) WriteAttribute("title", Tuple.Create(" title=\"", 2132), Tuple.Create("\"", 2170)
#line 38 "..\..\Views\Job\JobParts\Resources.cshtml" #line 38 "..\..\Views\Job\JobParts\Resources.cshtml"
, Tuple.Create(Tuple.Create("", 2099), Tuple.Create<System.Object, System.Int32>(jl.Timestamp.ToFullDateTime() , Tuple.Create(Tuple.Create("", 2140), Tuple.Create<System.Object, System.Int32>(jl.Timestamp.ToFullDateTime()
#line default #line default
#line hidden #line hidden
, 2099), false) , 2140), false)
); );
WriteLiteral(">"); WriteLiteral(">");
@@ -324,14 +323,14 @@ WriteLiteral(">\r\n <div");
WriteLiteral(" id=\"Attachments\""); WriteLiteral(" id=\"Attachments\"");
WriteAttribute("class", Tuple.Create(" class=\"", 2948), Tuple.Create("\"", 3023) WriteAttribute("class", Tuple.Create(" class=\"", 2989), Tuple.Create("\"", 3064)
#line 56 "..\..\Views\Job\JobParts\Resources.cshtml" #line 56 "..\..\Views\Job\JobParts\Resources.cshtml"
, Tuple.Create(Tuple.Create("", 2956), Tuple.Create<System.Object, System.Int32>(canAddAttachments ? "canAddAttachments" : "cannotAddAttachments" , Tuple.Create(Tuple.Create("", 2997), Tuple.Create<System.Object, System.Int32>(canAddAttachments ? "canAddAttachments" : "cannotAddAttachments"
#line default #line default
#line hidden #line hidden
, 2956), false) , 2997), false)
); );
WriteLiteral(">\r\n <div"); WriteLiteral(">\r\n <div");
@@ -361,14 +360,14 @@ WriteLiteral(">\r\n");
#line hidden #line hidden
WriteLiteral(" <a"); WriteLiteral(" <a");
WriteAttribute("href", Tuple.Create(" href=\"", 3360), Tuple.Create("\"", 3417) WriteAttribute("href", Tuple.Create(" href=\"", 3401), Tuple.Create("\"", 3458)
#line 63 "..\..\Views\Job\JobParts\Resources.cshtml" #line 63 "..\..\Views\Job\JobParts\Resources.cshtml"
, Tuple.Create(Tuple.Create("", 3367), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.Job.AttachmentDownload(ja.Id)) , Tuple.Create(Tuple.Create("", 3408), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.Job.AttachmentDownload(ja.Id))
#line default #line default
#line hidden #line hidden
, 3367), false) , 3408), false)
); );
WriteLiteral(" data-attachmentid=\""); WriteLiteral(" data-attachmentid=\"");
@@ -397,42 +396,42 @@ WriteLiteral(">\r\n <span");
WriteLiteral(" class=\"icon\""); WriteLiteral(" class=\"icon\"");
WriteAttribute("title", Tuple.Create(" title=\"", 3527), Tuple.Create("\"", 3547) WriteAttribute("title", Tuple.Create(" title=\"", 3568), Tuple.Create("\"", 3588)
#line 64 "..\..\Views\Job\JobParts\Resources.cshtml" #line 64 "..\..\Views\Job\JobParts\Resources.cshtml"
, Tuple.Create(Tuple.Create("", 3535), Tuple.Create<System.Object, System.Int32>(ja.Filename , Tuple.Create(Tuple.Create("", 3576), Tuple.Create<System.Object, System.Int32>(ja.Filename
#line default #line default
#line hidden #line hidden
, 3535), false) , 3576), false)
); );
WriteLiteral(">\r\n <img"); WriteLiteral(">\r\n <img");
WriteLiteral(" alt=\"Attachment Thumbnail\""); WriteLiteral(" alt=\"Attachment Thumbnail\"");
WriteAttribute("src", Tuple.Create(" src=\"", 3618), Tuple.Create("\"", 3677) WriteAttribute("src", Tuple.Create(" src=\"", 3659), Tuple.Create("\"", 3718)
#line 65 "..\..\Views\Job\JobParts\Resources.cshtml" #line 65 "..\..\Views\Job\JobParts\Resources.cshtml"
, Tuple.Create(Tuple.Create("", 3624), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.Job.AttachmentThumbnail(ja.Id)) , Tuple.Create(Tuple.Create("", 3665), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.Job.AttachmentThumbnail(ja.Id))
#line default #line default
#line hidden #line hidden
, 3624), false) , 3665), false)
); );
WriteLiteral(" /></span>\r\n <span"); WriteLiteral(" /></span>\r\n <span");
WriteLiteral(" class=\"comments\""); WriteLiteral(" class=\"comments\"");
WriteAttribute("title", Tuple.Create(" title=\"", 3744), Tuple.Create("\"", 3764) WriteAttribute("title", Tuple.Create(" title=\"", 3785), Tuple.Create("\"", 3805)
#line 66 "..\..\Views\Job\JobParts\Resources.cshtml" #line 66 "..\..\Views\Job\JobParts\Resources.cshtml"
, Tuple.Create(Tuple.Create("", 3752), Tuple.Create<System.Object, System.Int32>(ja.Comments , Tuple.Create(Tuple.Create("", 3793), Tuple.Create<System.Object, System.Int32>(ja.Comments
#line default #line default
#line hidden #line hidden
, 3752), false) , 3793), false)
); );
WriteLiteral(">\r\n"); WriteLiteral(">\r\n");
@@ -495,7 +494,7 @@ WriteLiteral("</span>");
#line 71 "..\..\Views\Job\JobParts\Resources.cshtml" #line 71 "..\..\Views\Job\JobParts\Resources.cshtml"
if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ja.TechUserId == CurrentUser.UserId)) if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ja.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
{ {
#line default #line default
@@ -527,14 +526,14 @@ WriteLiteral(" data-livestamp=\"");
#line hidden #line hidden
WriteLiteral("\""); WriteLiteral("\"");
WriteAttribute("title", Tuple.Create(" title=\"", 4459), Tuple.Create("\"", 4497) WriteAttribute("title", Tuple.Create(" title=\"", 4541), Tuple.Create("\"", 4579)
#line 72 "..\..\Views\Job\JobParts\Resources.cshtml" #line 72 "..\..\Views\Job\JobParts\Resources.cshtml"
, Tuple.Create(Tuple.Create("", 4467), Tuple.Create<System.Object, System.Int32>(ja.Timestamp.ToFullDateTime() , Tuple.Create(Tuple.Create("", 4549), Tuple.Create<System.Object, System.Int32>(ja.Timestamp.ToFullDateTime()
#line default #line default
#line hidden #line hidden
, 4467), false) , 4549), false)
); );
WriteLiteral(">"); WriteLiteral(">");
@@ -36,7 +36,7 @@
{ @ua.DocumentTemplate.Description} { @ua.DocumentTemplate.Description}
else else
{ @ua.Comments }} { @ua.Comments }}
</span><span class="author">@ua.TechUser.ToStringFriendly()</span>@if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ua.TechUserId == CurrentUser.UserId)) </span><span class="author">@ua.TechUser.ToStringFriendly()</span>@if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ua.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
{<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" data-livestamp="@(ua.Timestamp.ToUnixEpoc())" title="@ua.Timestamp.ToFullDateTime()">@ua.Timestamp.ToFullDateTime()</span> {<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" data-livestamp="@(ua.Timestamp.ToUnixEpoc())" title="@ua.Timestamp.ToFullDateTime()">@ua.Timestamp.ToFullDateTime()</span>
</a> </a>
} }
@@ -2,7 +2,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Runtime Version:4.0.30319.34014 // Runtime Version:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -27,7 +27,6 @@ namespace Disco.Web.Views.User.UserParts
using System.Web.UI; using System.Web.UI;
using System.Web.WebPages; using System.Web.WebPages;
using Disco; using Disco;
using Disco.BI.Extensions;
using Disco.Models.Repository; using Disco.Models.Repository;
using Disco.Services; using Disco.Services;
using Disco.Services.Authorization; using Disco.Services.Authorization;
@@ -37,9 +36,9 @@ namespace Disco.Web.Views.User.UserParts
[System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "2.0.0.0")] [System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "2.0.0.0")]
[System.Web.WebPages.PageVirtualPathAttribute("~/Views/User/UserParts/_Resources.cshtml")] [System.Web.WebPages.PageVirtualPathAttribute("~/Views/User/UserParts/_Resources.cshtml")]
public partial class Resources : Disco.Services.Web.WebViewPage<Disco.Web.Models.User.ShowModel> public partial class _Resources : Disco.Services.Web.WebViewPage<Disco.Web.Models.User.ShowModel>
{ {
public Resources() public _Resources()
{ {
} }
public override void Execute() public override void Execute()
@@ -256,7 +255,7 @@ WriteLiteral("</span>");
#line 39 "..\..\Views\User\UserParts\_Resources.cshtml" #line 39 "..\..\Views\User\UserParts\_Resources.cshtml"
if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ua.TechUserId == CurrentUser.UserId)) if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ua.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
{ {
#line default #line default
@@ -288,14 +287,14 @@ WriteLiteral(" data-livestamp=\"");
#line hidden #line hidden
WriteLiteral("\""); WriteLiteral("\"");
WriteAttribute("title", Tuple.Create(" title=\"", 2487), Tuple.Create("\"", 2525) WriteAttribute("title", Tuple.Create(" title=\"", 2528), Tuple.Create("\"", 2566)
#line 40 "..\..\Views\User\UserParts\_Resources.cshtml" #line 40 "..\..\Views\User\UserParts\_Resources.cshtml"
, Tuple.Create(Tuple.Create("", 2495), Tuple.Create<System.Object, System.Int32>(ua.Timestamp.ToFullDateTime() , Tuple.Create(Tuple.Create("", 2536), Tuple.Create<System.Object, System.Int32>(ua.Timestamp.ToFullDateTime()
#line default #line default
#line hidden #line hidden
, 2495), false) , 2536), false)
); );
WriteLiteral(">"); WriteLiteral(">");