99using System . Text . RegularExpressions ;
1010using System . Threading ;
1111using ServiceStack . Text ;
12+ using ServiceStack . Text . Common ;
1213
1314namespace ServiceStack
1415{
1516 public class LicenseException : Exception
1617 {
1718 public LicenseException ( string message ) : base ( message ) { }
19+ public LicenseException ( string message , Exception innerException ) : base ( message , innerException ) { }
1820 }
1921
2022 public enum LicenseType
@@ -182,17 +184,7 @@ public static void RegisterLicense(string licenseKeyText)
182184 throw new LicenseException ( "This subscription has been revoked. " + ContactDetails ) ;
183185
184186 var key = PclExport . Instance . VerifyLicenseKeyText ( licenseKeyText ) ;
185-
186- var releaseDate = Env . GetReleaseDate ( ) ;
187- if ( releaseDate > key . Expiry )
188- throw new LicenseException ( "This license has expired on {0} and is not valid for use with this release."
189- . Fmt ( key . Expiry . ToString ( "d" ) ) + ContactDetails ) . Trace ( ) ;
190-
191- if ( key . Type == LicenseType . Trial && DateTime . UtcNow > key . Expiry )
192- throw new LicenseException ( "This trial license has expired on {0}."
193- . Fmt ( key . Expiry . ToString ( "d" ) ) + ContactDetails ) . Trace ( ) ;
194-
195- __activatedLicense = key ;
187+ ValidateLicenseKey ( key ) ;
196188 }
197189 catch ( Exception ex )
198190 {
@@ -201,9 +193,22 @@ public static void RegisterLicense(string licenseKeyText)
201193
202194 var msg = "This license is invalid." + ContactDetails ;
203195 if ( ! string . IsNullOrEmpty ( subId ) )
204- msg += " The id for this license is '{0 }'" . Fmt ( subId ) ;
196+ msg += $ " The id for this license is '{ subId } '";
205197
206- throw new LicenseException ( msg ) . Trace ( ) ;
198+ lock ( typeof ( LicenseUtils ) )
199+ {
200+ try
201+ {
202+ var key = PclExport . Instance . VerifyLicenseKeyTextFallback ( licenseKeyText ) ;
203+ ValidateLicenseKey ( key ) ;
204+ }
205+ catch ( Exception exFallback )
206+ {
207+ throw new LicenseException ( msg , exFallback ) . Trace ( ) ;
208+ }
209+ }
210+
211+ throw new LicenseException ( msg , ex ) . Trace ( ) ;
207212 }
208213 finally
209214 {
@@ -213,6 +218,19 @@ public static void RegisterLicense(string licenseKeyText)
213218 }
214219 }
215220
221+ private static void ValidateLicenseKey ( LicenseKey key )
222+ {
223+ var releaseDate = Env . GetReleaseDate ( ) ;
224+ if ( releaseDate > key . Expiry )
225+ throw new LicenseException ( $ "This license has expired on { key . Expiry : d} and is not valid for use with this release."
226+ + ContactDetails ) . Trace ( ) ;
227+
228+ if ( key . Type == LicenseType . Trial && DateTime . UtcNow > key . Expiry )
229+ throw new LicenseException ( $ "This trial license has expired on { key . Expiry : d} ." + ContactDetails ) . Trace ( ) ;
230+
231+ __activatedLicense = key ;
232+ }
233+
216234 public static void RemoveLicense ( )
217235 {
218236 __activatedLicense = null ;
@@ -365,7 +383,7 @@ public static LicenseKey ToLicenseKey(this string licenseKeyText)
365383 var key = jsv . FromJsv < LicenseKey > ( ) ;
366384
367385 if ( key . Ref != refId )
368- throw new LicenseException ( "The license '{0}' is not assigned to CustomerId '{1}'." . Fmt ( base64 ) ) . Trace ( ) ;
386+ throw new LicenseException ( "The license '{0}' is not assigned to CustomerId '{1}'." . Fmt ( base64 , refId ) ) . Trace ( ) ;
369387
370388 return key ;
371389 }
@@ -376,9 +394,33 @@ public static LicenseKey ToLicenseKey(this string licenseKeyText)
376394 }
377395 }
378396
397+ public static LicenseKey ToLicenseKeyFallback ( this string licenseKeyText )
398+ {
399+ licenseKeyText = Regex . Replace ( licenseKeyText , @"\s+" , "" ) ;
400+ var parts = licenseKeyText . SplitOnFirst ( '-' ) ;
401+ var refId = parts [ 0 ] ;
402+ var base64 = parts [ 1 ] ;
403+ var jsv = Convert . FromBase64String ( base64 ) . FromUtf8Bytes ( ) ;
404+
405+ var map = jsv . FromJsv < Dictionary < string , string > > ( ) ;
406+ var key = new LicenseKey
407+ {
408+ Ref = map . Get ( "Ref" ) ,
409+ Name = map . Get ( "Name" ) ,
410+ Type = ( LicenseType ) Enum . Parse ( typeof ( LicenseType ) , map . Get ( "Type" ) ) ,
411+ Hash = map . Get ( "Hash" ) ,
412+ Expiry = DateTimeSerializer . ParseManual ( map . Get ( "Expiry" ) , DateTimeKind . Utc ) . GetValueOrDefault ( ) ,
413+ } ;
414+
415+ if ( key . Ref != refId )
416+ throw new LicenseException ( $ "The license '{ base64 } ' is not assigned to CustomerId '{ refId } '.") . Trace ( ) ;
417+
418+ return key ;
419+ }
420+
379421 public static string GetHashKeyToSign ( this LicenseKey key )
380422 {
381- return "{0 }:{1 }:{2}:{3}" . Fmt ( key . Ref , key . Name , key . Expiry . ToString ( " yyyy-MM-dd" ) , key . Type ) ;
423+ return $ " { key . Ref } :{ key . Name } :{ key . Expiry : yyyy-MM-dd} : { key . Type } " ;
382424 }
383425
384426 public static Exception GetInnerMostException ( this Exception ex )
0 commit comments