Compare commits

..

310 Commits

Author SHA1 Message Date
Sebastien Ros
248cc7ecde Updating webpi package files 2015-09-21 15:29:31 -07:00
Sébastien Ros
bb41f1f559 Merge pull request #5831 from OrchardCMS/feature/ownmedia
Implementing own media management
2015-09-21 15:08:19 -07:00
Sébastien Ros
5903f75665 Merge pull request #5828 from OrchardCMS/feature/layoutpermission
Adding ManageLayout permission
2015-09-21 15:07:57 -07:00
Sébastien Ros
46182edc5d Merge pull request #5827 from rtpHarry/1.9.x
[Fixes #5826] Restore placements confirmation message fix
2015-09-21 14:36:44 -07:00
Sebastien Ros
accd4196dc Implementing own media management 2015-09-21 14:09:37 -07:00
Sebastien Ros
d3d85f3519 Adding ManageLayout permission 2015-09-21 14:04:37 -07:00
Sébastien Ros
6e90f704f8 Merge pull request #5833 from mjy78/issue/5829
[Fixes #5829] Cannot delete spam comment when viewing comment details
2015-09-21 13:02:32 -07:00
Sébastien Ros
497b782a6a Merge pull request #5837 from mjy78/issue/5836
#5836 Fix null ref exception in CommentPartDriver
2015-09-21 12:58:01 -07:00
Sebastien Ros
bc935f18b3 Fixing unit tests 2015-09-21 12:45:57 -07:00
Sebastien Ros
12a51ea7af [Fixes #5751, #5794] Removing Edit inline 2015-09-21 12:08:19 -07:00
Sebastien Ros
f0b1639143 [Fixes #5616] Revert "Using master content item to create translations"
This reverts commit fa09e2e83a.
2015-09-21 11:27:46 -07:00
myates
9bb95efaaa #5836 Fix null ref exception in CommentPartDriver 2015-09-21 10:26:14 +10:00
myates
e6c042d1a0 Fix build error 2015-09-19 22:03:12 +10:00
myates
df583ea571 Merge branch 'Orchard-1.9.x' into issue/5829 2015-09-19 21:20:21 +10:00
myates
adbab55ffc Comment service now fetches latest (instead of published) when deleting a comment. 2015-09-18 16:45:10 +10:00
Matthew Harris
20fbd99658 updated all instances of RemoveUrl checks 2015-09-17 22:58:58 +01:00
Matthew Harris
d9a0e040c1 don't overwrite confirmRemoveMessage 2015-09-17 22:54:47 +01:00
Matthew Harris
4aaf4d34d0 amends based on PR feedback 2015-09-17 21:58:12 +01:00
Matthew Harris
7143792c0e fix #5826 2015-09-17 19:44:25 +01:00
Sebastien Ros
4214329a1f Prevent unnecessary db calls for containers 2015-09-16 17:52:33 -07:00
Sebastien Ros
921b2472f1 Adding filter for own content 2015-09-16 17:52:27 -07:00
Sebastien Ros
9e9e19c439 Add setting to hide Container editor 2015-09-16 17:52:13 -07:00
Sebastien Ros
f3595881fe Hide taxonomy link if permission is not granted 2015-09-16 17:52:04 -07:00
Sebastien Ros
ba36eae848 Prevent MediaLibrary popup without permissions
If the user doesn't have ManageMedia permissions,
the markdown editor will use a specific image editor.
2015-09-16 17:51:50 -07:00
Sebastien Ros
0bf76dc7ac Implementing a positioned wrapper for text elements
When adding a text directly to a zone, the position will now
be taken into account. This is also useful for the Capture feature.

Conflicts:
	src/Orchard/Orchard.Framework.csproj
2015-09-16 17:51:23 -07:00
Sipke Schoorstra
66ff5d36e9 Merge pull request #5810 from Codinlab/issue/5809
Fixes #5809 : Layouts : DisplayText encoded twice in Design mode
2015-09-15 14:03:55 +01:00
Thierry Fleury
749ff5dc72 Fixes #5809 : Layouts : DisplayText encoded twice in Design mode 2015-09-15 14:53:52 +02:00
Nicholas Mayne
85c4a99c13 Merge pull request #5798 from mvarblow/patch-4
Fixed typo in Sites.Config comment.
2015-09-13 17:35:28 +01:00
Sipke Schoorstra
a3fe3592c6 Merge pull request #5799 from mvarblow/patch-5
Code clean-up in TermCountProcessor.cs
2015-09-13 13:42:39 +01:00
mvarblow
a2c31a1e5c Code clean-up in TermCountProcessor.cs
Removed an unused field and unused using statements.
2015-09-13 08:33:08 -04:00
mvarblow
3f6dfa3dec Fixed typo in Sites.Config comment. 2015-09-12 20:54:54 -04:00
Sébastien Ros
f9ef297777 Merge pull request #5780 from mjy78/issue/5779
[Fixes #5779] Query and Taxonomy Elements should include value attribute for default option
2015-09-11 15:07:51 -07:00
Sébastien Ros
801b8998db Merge pull request #5783 from mjy78/issue/20377
[Fixes #4206] Ensure comment tokens available to anti-spam module.
2015-09-11 15:03:45 -07:00
myates
92b7ad7554 Issue 20377 - Ensure comment tokens available to antispam module. 2015-09-11 17:15:42 +10:00
myates
18bb847488 Force empty value attribute on default option label in taxonomy and query element dropdown lists. 2015-09-11 14:19:52 +10:00
Sébastien Ros
47133604c3 Merge pull request #5676 from RoyalVeterinaryCollege/3404
[Fixes #3404] Added Required attribute to Enumeration and Numeric Fields
2015-09-10 12:24:28 -07:00
Sebastien Ros
80b93e412a Supporting custom display type for search results 2015-09-09 15:44:53 -07:00
Sebastien Ros
e839f84537 Fixing unit test
The ThemeExtensionFolder stub should have been used
2015-09-09 14:53:16 -07:00
Sebastien Ros
a548e47f90 [Fixes #5283] Adding some documentation for ResourceDefinition.SetVersion
It has to be a vallid SermVer format.
2015-09-09 14:52:41 -07:00
Sebastien Ros
89e8658f49 Improving protected zones in settings UI
Protecting MaxPagedCount
Protecting BaseUrl
Unhiding BaseUrl and SuperUser so that users can see what the values are
2015-09-09 11:27:18 -07:00
Sebastien Ros
6d255f24ab Fixing exception when the Default layer doesn't exist 2015-09-09 09:25:01 -07:00
Sebastien Ros
e8f0ba6ec7 Fixing RecipeManagerTests 2015-09-08 17:12:44 -07:00
Sebastien Ros
60798f9346 Fixing TokenManagerTests 2015-09-08 17:09:53 -07:00
Sebastien Ros
c83f5d88cb Supporting lazy cache manager resolution 2015-09-08 17:04:45 -07:00
Sebastien Ros
2f2134412e [Fixes #5492] Adding JavaScriptEncode token 2015-09-08 16:13:55 -07:00
Sébastien Ros
1e6b6bb24f Merge pull request #5568 from Codinlab/Tokens
Token chaining improvements
2015-09-08 16:08:17 -07:00
Sébastien Ros
16de29dabd Merge pull request #5652 from Codinlab/issues/5614
Fixes #5614 : ContentPickerField and LayoutPart issue
2015-09-08 15:57:38 -07:00
Sebastien Ros
691809cd85 [Fixes #5733] Update default Layout state settings 2015-09-08 15:40:28 -07:00
Sébastien Ros
ce1df8d794 Merge pull request #5677 from dcinzona/Gulpfile-watch-assets.json
Enables gulp watch of Assets.json
2015-09-08 11:37:54 -07:00
Sébastien Ros
74be36d8a3 Merge pull request #5763 from phillipsj/1.9.x
Updating DynamicForms Module.txt
2015-09-08 11:11:12 -07:00
Jamie Phillips
2bb7eb2f91 Updating DynamicForms Module.txt
The CustomForms module name and website were listed.
2015-09-08 13:06:04 -04:00
Sebastien Ros
c4592aa65f Selecting the layer "Default" on the widgets start screen
Fixes a specflow bug which expect "Default" to be the default
selected layer. Appeared since layers are ordered alphabetically.
2015-09-08 09:27:36 -07:00
Sebastien Ros
9bac35b3f1 Removing duplicated using 2015-09-08 09:12:26 -07:00
Lombiq
2a0f866f26 Fixing exception when importing Projection Elements with the default layout selected
Fixed the export of this previously, this was remaining.
2015-09-08 01:01:23 +02:00
Thierry Fleury
371238a882 Add parameterized tokens tests 2015-09-07 15:14:20 +02:00
Thierry Fleury
67e7d1074e Allow Text token chaining when possible.
Correct some errors on token descriptions.
2015-09-07 11:57:20 +02:00
Thierry Fleury
25c34d8bca Fixes #5563 : Allow token chaining on DynamicForms submissions. 2015-09-07 11:57:19 +02:00
Thierry Fleury
75f3a618f0 Enhances TaxonomyField's token chaining. 2015-09-07 11:57:18 +02:00
Thierry Fleury
9947f3973e Add new Chain method for tokens
The new method allows working with parameterized tokens.
2015-09-07 11:57:17 +02:00
Lombiq
a685517118 Normalizing all catch (Exception ex) lines and adding exception fatality check where applicable, fixes #3949 2015-09-07 00:17:57 +02:00
Daniel Stolt
14482162fd Marked some tests as long-running. Fixes #5702. 2015-09-06 00:31:15 +02:00
Sébastien Ros
0f757655b8 Merge pull request #5736 from Codinlab/issue/5735
Fixes #5735 : ContentType name encoding in Lists
2015-09-04 16:35:03 -07:00
Sebastien Ros
39fb266221 Skipping DateTime tests until the right solution is found
c.f. #5702
2015-09-04 15:59:24 -07:00
Sebastien Ros
9b91b1b260 Removing unnecessary resolution 2015-09-04 13:20:08 -07:00
Sebastien Ros
c2194381f8 Removing unused usings 2015-09-04 12:12:13 -07:00
Sebastien Ros
c860b89e23 Removed erroneous HttpContextBase registrations 2015-09-04 12:12:02 -07:00
Sebastien Ros
04f29ba70c Revert "Cherry picked ce630f980c7a79ae17b36598f3834c4ffd523739."
This reverts commit aba53e122d.

Conflicts:
	src/Orchard.Web/Modules/Orchard.Layouts/Handlers/LayoutPartHandler.cs
	src/Orchard/Mvc/HttpContextAccessor.cs
	src/Orchard/Mvc/IHttpContextAccessor.cs
	src/Orchard/Mvc/MvcModule.cs
	src/Orchard/Orchard.Framework.csproj
	src/Orchard/Tasks/BackgroundService.cs
2015-09-04 10:59:31 -07:00
Sébastien Ros
e118695ea7 Merge pull request #5738 from harmony7/4852-orchardshellevents-workcontext
#4852: Wrap IOrchardShellEvents in a work context
2015-09-04 10:09:36 -07:00
Thierry Fleury
894e90f485 Use new ActionLink extension method. 2015-09-04 15:08:30 +02:00
Thierry Fleury
97bb52bbdd Add LinkExtensions
Allows using IHtmlString as linkText
2015-09-04 15:05:25 +02:00
Sébastien Ros
f3d08d61c4 Merge pull request #5741 from mvarblow/patch-2
Mark the npm repository as private
2015-09-03 14:24:05 -07:00
Sébastien Ros
22697edeec Merge pull request #5742 from mvarblow/patch-3
Suppressed warning CS0436 in Orchard.Framework
2015-09-03 14:23:26 -07:00
mvarblow
e0fc576f9e Suppressed warning CS0436 in Orchard.Framework
Daniel changed the Orchaard.Framework project to ignore the JetBrains.Annotations conflicts for debug builds several months back. See http://orchard.codeplex.com/workitem/21056 and 78901ba . However, the problem still exists for release builds. This pull request applies the same fix (ignoring the warning) to release builds.
2015-09-03 16:07:06 -04:00
mvarblow
ef9e5de8f4 Mark the npm repository as private
'npm install' was generating several warnings about missing properties in package.json. Marking the repository as private clears up the warnings.
2015-09-03 16:03:39 -04:00
harmony7@pex2.jp
5878611817 Wrap IOrchardShellEvents in a work context. 2015-09-03 22:19:21 +09:00
Thierry Fleury
f5772334e1 Fixes #5735 : ContentType name encoding in Lists 2015-09-03 10:05:02 +02:00
Lombiq
fcc4a944bb Fixing that Projection Elements with the Default Layout selected weren't exported 2015-08-30 22:29:12 +02:00
Sebastien Ros
a0d61c67b8 Refactoring Import methods 2015-08-28 17:06:34 -07:00
Lombiq
42ff708da8 #5664: Lucene should page operations with the highest possible page size 2015-08-28 23:38:30 +02:00
Sebastien Ros
b52a846c5f #5664: Lucene should page operations
Fixes #5664
2015-08-27 15:31:39 -07:00
Sébastien Ros
9a8b64393e Merge pull request #5671 from RoyalVeterinaryCollege/4352
#4352: orphaned awaitingactivities

Fixes #4352
2015-08-27 12:39:24 -07:00
Jeff
bd1f14eeb0 Fix Issue #4352: Added prompt on workflow save to give choice of stopping running workflows. 2015-08-27 10:59:50 +01:00
Sebastien Ros
4b59569013 #5490 Fixing HttpRequestBase DependenciesShouldBeUpgradedFirst
Fixes #5490
2015-08-26 17:19:04 -07:00
Sébastien Ros
a603c7e07a Merge pull request #5678 from jchenga/issues/5618
#5618 taxonomy in autoroute needs to be saved twice

Fixes #5618
2015-08-26 16:48:13 -07:00
Sebastien Ros
96f6cb36fd Reverting session factory changes 2015-08-26 16:40:02 -07:00
Sébastien Ros
3d63c6d333 Merge pull request #5544 from yw80/patch-2
Remove the blank line at the bottom of every page after the default theme rendering.
2015-08-26 16:11:35 -07:00
Sébastien Ros
4cdb081c9d Merge pull request #5543 from yw80/patch-1
Correct CSS class name of MediaLibraryPickerField field
2015-08-26 16:05:16 -07:00
Sébastien Ros
9ed6b4261d Merge pull request #5542 from jtkech/patch-2
##5369: Allows simple properties null checking on a dynamic ContentItem or ContentPart

Fixes #5369
2015-08-26 16:04:09 -07:00
Sébastien Ros
a0e78f2eb0 Merge pull request #5571 from jersiovic/patch-6
Fixed #5140 Recipe from Migrations didn't work
2015-08-26 15:59:03 -07:00
Sébastien Ros
af4e41a717 Merge pull request #5667 from qt1/IBN-Labs/ItemEditLink_htmlAttributes
Support htmlAttributes in ItemEditLink

Fixes #5666
2015-08-26 15:54:13 -07:00
Sebastien Ros
7f91e787de Adding debug log when content item is imported 2015-08-26 14:44:56 -07:00
Sebastien Ros
6810cf473f Updating indexing tasks when content is imported or restored 2015-08-26 14:44:50 -07:00
Sebastien Ros
79a0ae86e8 Create index command should not delete existing index 2015-08-26 14:44:40 -07:00
Sebastien Ros
4cec35daf8 Disposing the session when a transaction is rolled back 2015-08-26 14:44:32 -07:00
Sebastien Ros
8d4cb98d59 Adding missing content handler Restore events 2015-08-26 14:44:25 -07:00
Sebastien Ros
e6424e2589 Removing empty folder 2015-08-26 14:44:15 -07:00
Sebastien Ros
dcc7783f12 Adding storage filter events for Import/Export 2015-08-26 09:47:39 -07:00
Sebastien Ros
d35ebe04e7 Adding User identity resolver
To improve import step for Users
2015-08-26 09:47:26 -07:00
Sebastien Ros
c80f2d4baa Fixing Search settings export 2015-08-26 09:46:46 -07:00
Sébastien Ros
9a4e0c1741 Merge pull request #5694 from dcinzona/patch-2
Fixes #5693 - DisableTheme Part breaks admin theme
2015-08-25 09:56:31 -07:00
Gustavo Tandeciarz
47d3d2b738 Fixes #5693
Will not disable the admin theme.
2015-08-25 12:54:26 -04:00
Sipke Schoorstra
e0e600a6ce Merge pull request #5688 from Codinlab/issue/5475
Fixes #5475 : Add missing properties to HttpRequestPlaceholder
2015-08-24 10:42:51 +01:00
Thierry Fleury
21875b98cc Fixes #5475 : Add missing properties to HttpRequestPlaceholder 2015-08-24 11:39:01 +02:00
Jack Cheng
28a1b4d663 #5618 taxonomy in autoroute needs to be saved twice
Fixes 5618
2015-08-21 19:27:29 -07:00
Gustavo Tandeciarz
bbcdd67b95 Cleanup
gulp-util was previously used during development and is no longer required.
2015-08-21 20:15:51 -04:00
Gustavo Tandeciarz
cfc1dc2379 Enables gulp watch of Assets.json
Will restart the watch task when Assets.json is changed.
2015-08-21 20:08:41 -04:00
Sebastien Ros
9e95f96195 Supporting .. syntax in watched assets 2015-08-21 16:01:44 -07:00
Jeff
770704f3a7 Added required attribute to enumeration and numeric fields.
Fixes #3404.
2015-08-21 16:40:01 +01:00
qt1
d9a3db1ebf Support htmlAttributes in ItemEditLink 2015-08-21 03:09:50 +03:00
Thierry Fleury
9980633ac3 Use Enumerable.Empty 2015-08-20 23:57:38 +02:00
Sébastien Ros
5b42c707b1 Merge pull request #5627 from Codinlab/fixes/ContentTypeEncoding
Fixes 5591 : ContentType's name encoding
2015-08-20 13:03:28 -07:00
Sébastien Ros
83a35f89cf Merge pull request #5644 from mvarblow/patch-1
Allow for packaging a debug build
2015-08-20 12:22:00 -07:00
Thierry Fleury
746d3d54c2 Fixes 5614 : ContentPickerField and LayoutPart throws argument null exception. 2015-08-18 12:46:09 +02:00
Daniel Stolt
f19b57c1e6 Fixed one remaining unit datetime localization unit test on Windows 10. 2015-08-17 00:25:34 +01:00
Daniel Stolt
7533cd8879 Improved DateTime localization and unit tests on Windows 10.
Added support for era names to date formatting/parsing framework. Added handling of cultures with missing AM/PM designators. Fixes failing unit tests on Windows 10. Fixes #5595.
2015-08-17 00:01:32 +01:00
Daniel Stolt
75609bf2ce Excluded private locator URLs from JSON serialization in Azure Media Services. Fixes #4686. 2015-08-16 20:13:33 +01:00
Daniel Stolt
4b44827f2a Added skeleton Assets.json to codegen theme template. 2015-08-16 17:50:47 +01:00
Daniel Stolt
a04195ee0e Added a simple skeleton Assets.json to codegen module template. Fixes #5606. 2015-08-16 17:38:16 +01:00
Daniel Stolt
b2c131f516 Refactored watch task in Gulpfile.js. 2015-08-16 16:15:46 +01:00
Daniel Stolt
359d25c1f2 Merge branch 'patch-5' of https://github.com/dcinzona/Orchard into 1.9.x 2015-08-16 14:43:36 +01:00
Lombiq
6552735df3 Media Library now correctly handles files with a # character in their name, fixes #5421. 2015-08-16 02:23:11 +02:00
Lombiq
59b3d50e03 Fixing that the empty username validation message wasn't shown on the Lost Password page, fixes #5353 2015-08-16 02:08:12 +02:00
Daniel Stolt
f2bf75328e Merge pull request #5642 from paynecrl97/5520/tenantAwareConfig
#5520 AppConfigurationAccessor is now tenant aware.

Fixes #5520.
2015-08-14 11:43:09 +01:00
Chris Payne
0213524317 AppConfigurationAccessor is now tenant aware 2015-08-14 11:34:28 +01:00
mvarblow
fd931397a4 Allow for packing a debug build
We use the orchard packaging script for continuous deployments to QA servers where we'd like to run debug builds.
2015-08-13 12:01:35 -04:00
Lombiq
64585223ee Fixing that Layouts couldn't be export/imported properly because they lacked an identity 2015-08-13 17:02:50 +02:00
Sipke Schoorstra
564fdc27be #5636: Fixed a bug with AliasStorage.Remove method.
Fixes #5636
2015-08-13 13:48:37 +01:00
Lombiq
06e4d2f7f8 Fixing typo/language 2015-08-11 02:04:57 +02:00
Thierry Fleury
cc70480126 Fixes 5591 : ContentType's name encoding 2015-08-10 15:28:19 +02:00
Gustavo Tandeciarz
7bcb6b83fb Update Package.json
Removed Gulp Notify as it is not required.
2015-08-10 08:08:29 -04:00
Gustavo Tandeciarz
e72471f020 Moved watchPaths in gulpfile
Moved the watchPaths generation to the watch task.
Cleaned up some spacing
2015-08-10 08:07:49 -04:00
Gustavo Tandeciarz
de74c00378 Updates to gulpfile.js
Removed comments and notify, as well as console.logs.
2015-08-10 07:53:19 -04:00
Sébastien Ros
b206a656e8 Merge pull request #5603 from mahsaro/WidgetLayersOrder_1.9.x
Ordered layers alphabetically in Widget admin UI.
2015-08-06 12:41:19 -07:00
Sébastien Ros
32669d347a Merge pull request #5610 from psenechal/1.9.x
Update Module.txt
2015-08-06 12:40:44 -07:00
Sébastien Ros
5bdfb6e98a Merge pull request #5476 from dcinzona/patch-1
Added mimetype declarations to root web.config
2015-08-06 12:40:01 -07:00
Lombiq
85fd5c8320 Fixing registration settings infoset migration 2015-08-06 21:30:35 +02:00
Sebastien Ros
41bd9ce9bc Adding a file system backed output cache provider 2015-08-05 16:59:34 -07:00
Sebastien Ros
e346170f24 Adding some documentation for IAppDataFolder 2015-08-05 14:21:22 -07:00
Gustavo Tandeciarz
b399925368 Updated Gulpfile.js
Switched property check to use `hasOwnProperty` instead of `!== undefined`
2015-08-05 08:42:08 -04:00
Gustavo Tandeciarz
ecbd485fd8 Updated Gulpfile.js
Removed variable option for rebuildAlways
Set watch task to always check `watchPaths` and populated that based on `watch` variable option (if the option is present, it will watch files designated in `watch` as well as files designated in `input`.  Otherwise, it will only watch files designated in `input`.
2015-08-05 08:28:08 -04:00
Gustavo Tandeciarz
0fcf8c7409 Updating gulpfile.js per request
Including some help text / comments
Set rebuildAlways to default to true when not specified
Set generateSourceMaps to default to true when not specified
Including files specified in 'inputs' into the watch list.
2015-08-05 06:37:46 -04:00
Sebastien Ros
430c3de460 Compressing output cache content in Redis 2015-08-04 17:28:49 -07:00
Philip Senechal
a6f5e4fb01 Update Module.txt
Spelling corrections
2015-08-04 16:25:30 -07:00
Philip Senechal
ff1fe79016 Update Module.txt
Language correction
2015-08-04 16:22:56 -07:00
Gustavo Tandeciarz
8e9f6ce8bd Adding gulp-notify package
required for gulpfile.js updates
2015-08-04 18:33:37 -04:00
Gustavo Tandeciarz
47e0b96725 Fixes #5607
Added optional properties to the Assets.json to support separating watch and build lists.
Also added support for excluding sourcemaps as well as forcing rebuild.

Requires gulp-notify (added fancier notification for process completion).
2015-08-04 18:31:55 -04:00
Sebastien Ros
f25758cc05 Refactoring connection multiplexer usage
For consistency with other services using Redis
2015-08-04 10:30:23 -07:00
Sebastien Ros
bb6a44634d Handling output cache provider exceptions 2015-08-04 10:29:46 -07:00
mahsaro
3657cfecab Ordered layers alphabetically in Widget admin UI. 2015-08-04 15:02:08 +01:00
Sebastien Ros
8a08680a74 Localizing RedisTagCache keys 2015-08-03 14:37:25 -07:00
Sebastien Ros
25670b9620 Fixing pager text encoding
Fixes #5359
2015-07-31 17:00:31 -07:00
Sebastien Ros
fa09e2e83a Using master content item to create translations
Fixes #5535
2015-07-31 16:19:34 -07:00
Sebastien Ros
a9a1413331 Fixing unit tests 2015-07-31 16:12:36 -07:00
Sebastien Ros
637cea6a02 Fixing Redis connection creation
With the previous code, when multiple threads tried to create
a Redis connection, the ConcurrentDictionary would have
called the factory delegate multiple times and added only one
of the resulting connections. This is by design, and a solution
is to use a Lazy object to defer the creation of the connection.
Multiple Lazy objects will be created but it doesn't have any impact.
2015-07-31 15:10:08 -07:00
Sebastien Ros
cc82bfcca0 Fixing duplicate session creation 2015-07-30 15:49:13 -07:00
Daniel Stolt
faa216147d Merge pull request #5575 from Codinlab/issue/5519
Fixes #5519 : DynamicForms client validation issue
2015-07-29 16:59:40 +01:00
Sipke Schoorstra
cbf10216b0 Merge pull request #5581 from dcinzona/patch-4
Updated README.md Orchard version to 1.9.1
2015-07-28 15:14:00 +01:00
Gustavo Tandeciarz
bb560f9cdf Updated README.md Orchard version to 1.9.1
Was listing 1.8.1 as latest version in the readme. Minor update.
2015-07-28 08:57:49 -04:00
Thierry Fleury
bc2e0607ef DynamicForms : Mark css & js assets as content
MsBuild raise errors when ccs or js files have "None" BuildAction
2015-07-27 13:30:29 +02:00
Thierry Fleury
cd5ca49b32 Fixes #5519 : DynamicForms client validation issue
jQuery validate script order is important
2015-07-27 11:31:47 +02:00
Daniel Stolt
6da6c5c214 #5450: Implemented generalized Gulp automation.
Fixes #5446.
2015-07-26 01:14:14 +01:00
Lombiq
37a5a7effc Wrapping ITokenizer injection into Work<> for shape methods to prevent possible DependencyResolutionException.
Not doing this can cause "No scope with a Tag matching 'work' is visible from the scope in which the instance was requested." errors with certain token providers.
2015-07-26 00:53:19 +02:00
Nicholas Mayne
baad84ee7b Merge pull request #5570 from jtkech/patch-3
Incorrect plus characters break the compilation in DefaultDataMigrationInterpreter.cs
2015-07-25 21:23:58 +01:00
Sergio Navarro
8a8b0f91c6 Fixed #5140 Recipe from Migrations didn't work 2015-07-25 08:54:31 +02:00
jtkech
93476c321a Update DefaultDataMigrationInterpreter.cs
Remove incorrect plus characters that break the compilation
2015-07-24 20:31:25 +02:00
Sipke Schoorstra
ea91185816 Falling back to a default base URL in case none is configured.
This fixes an issue where you run Setup from a command line and the recipe does not set BaseUrl on site settings.
The issue is that if the HttpContext does not have a URL, certain properties on the Request object will throw when constructing a URI with a null value.
2015-07-24 10:34:37 +01:00
yw80
879e35dcc0 Correct CSS class name of MediaLibraryPickerField field
Field CSS class name should use the technical name, rather than the display name.
2015-07-24 12:21:31 +08:00
jtkech
e8111cef5e Update DynamicContentItemTests.cs
Adds an unit test for null checking on dynamic ContentItem / ContentPart properties
2015-07-24 02:54:01 +02:00
Sébastien Ros
c0ebbd4ce7 Merge pull request #5548 from minglei84/1.9.x
Fixed [Default Value] And [DropForeignKeyCommand] For Mysql
2015-07-23 12:35:15 -07:00
Nicholas Mayne
818b35a370 Merge pull request #5551 from Codinlab/issue/5519
Fixes #5519 : DynamicForms client validation
2015-07-23 17:22:12 +01:00
Sipke Schoorstra
34947136d4 Fixed and updated scripts and gulp in Dynamic Forms and Layouts. 2015-07-23 11:42:16 +01:00
Sebastien Ros
894d932210 Reverting changes on Orchard.proj for Kudu
Fixes #5557
2015-07-22 14:50:14 -07:00
Sebastien Ros
8032d202e3 Compiling the solution for CI tests 2015-07-22 14:36:57 -07:00
Sebastien Ros
046c62e710 Diagnosing CI failures (wip) 2015-07-22 14:19:28 -07:00
Sebastien Ros
9001972d8b Fixing functional tests execution
On .NET 4.6
2015-07-22 13:03:58 -07:00
Sebastien Ros
0fc8f5accf Updating Redis driver 2015-07-21 18:08:10 -07:00
Lombiq
2a34cb582b Reverting that form validation services of Dynamic Forms were moved to a separate feature (should be only on dev) 2015-07-21 23:42:58 +02:00
Daniel Stolt
7411013b45 Fixed a localization unit test that was failing on some cultures. 2015-07-21 22:11:54 +01:00
Thierry Fleury
0e7f864d4d Fixes #5519 : DynamicForms client validation 2015-07-21 12:17:58 +02:00
Murray Hou
14cdf57bc5 Fixed DropForeignKeyCommand For Mysql 2015-07-21 15:48:54 +08:00
Murray Hou
41e9fda2de Fixed [default value] For Mysql
The [default value] can'nt use [modify column] in mysql.
2015-07-21 15:38:21 +08:00
Sebastien Ros
e6211dbf54 Merge branch '1.9.x' of https://github.com/OrchardCMS/Orchard into 1.9.x 2015-07-20 14:31:33 -07:00
Sebastien Ros
1664aa1bde Fixing Setup due to missing dynamic forms feature 2015-07-20 14:30:57 -07:00
Sebastien Ros
1b54e3e8fb Restoring build log level 2015-07-20 14:29:56 -07:00
Sipke Schoorstra
5d09053d30 Fixed an issue when changing the homepage.
This fixes an issue where the previous published homepage would not have its regenerated alias stored.
2015-07-20 20:56:37 +01:00
Sipke Schoorstra
1494aec836 Removed mixed tabs and spaces. 2015-07-20 20:10:58 +01:00
yw80
a0f42632e0 Remove the blank line at the bottom of every page after the default theme rendering.
Set a background color to #layout-footer In Site.css, you can clearly see the blank line at the bottom.
2015-07-20 15:43:23 +08:00
jtkech
28643ae7b8 Update ContentPart.cs 2015-07-20 02:23:56 +02:00
jtkech
70ea2df334 Update ContentItem.cs 2015-07-20 02:11:49 +02:00
Sébastien Ros
e964d80f7e Merge pull request #5537 from jtkech/patch-1
#5512: Incorrect message of DynamicForms StringLength rule if only Maximum is specified
2015-07-19 09:58:24 -07:00
Nicholas Mayne
1e62b2b9f8 Merge pull request #5526 from yw80/1.9.x
Correct code indentation format for file IndexingTaskExecutor.cs
2015-07-19 17:53:25 +01:00
Nicholas Mayne
1732c333c2 Merge pull request #5540 from jchenga/issues/5539
[Fixes #5530] YSOD instead of the set up page in Azure.
2015-07-19 17:51:45 +01:00
Jack Cheng
a01d219607 [Fixes #5530] YSOD instead of the set up page in Azure. 2015-07-19 09:23:18 -07:00
Lombiq
36910e8659 Adding missing OrchardFeature attributes to Dynamic Forms validation services 2015-07-18 14:35:43 +02:00
jtkech
230314d7a1 Update StringLength.cs 2015-07-18 02:26:14 +02:00
Sebastien Ros
7282df4326 Adding support for Kudu deployment 2015-07-17 16:27:59 -07:00
Lombiq
81034f43d2 Fixing another potential NRE when saving a content item with LocalizationPart for the first time 2015-07-17 18:56:06 +02:00
yw80
30a95ed773 Correct CSS class name of MediaLibraryPickerField field
Field CSS class name should use the technical name, rather than the
display name.
2015-07-17 17:58:18 +08:00
Sipke Schoorstra
ddaf49db4a #5530: Fixed a spelling mistake in Layouts.
Fixes #5530
2015-07-17 09:46:53 +01:00
Daniel Stolt
3d3d6205b6 #5516: Changed DefaultDateLocalizationServices.ConvertFromLocalizedDateString() to return DateTimeKind.Utc and added unit test to verify.
Fixes #5516
2015-07-16 22:00:20 +01:00
yw80
e72d226263 Delete redundant text in file ShapeTracingTemplates.cshtml 2015-07-17 03:17:59 +08:00
yw80
4da838a3c3 Correct code indentation format for file IndexingTaskExecutor.cs
Incorrect indentation format causes code reading difficulties.
2015-07-17 03:03:53 +08:00
Sébastien Ros
d63119b1e6 Merge pull request #5433 from jersiovic/patch-3
Issue #5432 Differentiator is ignored processing placement
2015-07-16 12:02:46 -07:00
Nicholas Mayne
6bc98bede6 Merge pull request #5498 from yw80/1.9.x
Delete the CamelFriendly function call to DisplayName.
2015-07-16 15:23:00 +01:00
Lombiq
99e05c8a09 Fixing exception in Layouts when a driver was inherited from a custom base driver, fixes #5509 2015-07-16 12:11:38 +02:00
Sergio Navarro
3e1087ff58 Update ShapePlacementParsingStrategy.cs 2015-07-14 20:51:29 +02:00
Sergio Navarro
43315c349f Update ShapePlacementParsingStrategy.cs 2015-07-14 20:49:39 +02:00
Lombiq
e74b6ad6f8 Fixing potential NRE in LocalizationPartHandler by adding a nullcheck in LocalizationPartDriver 2015-07-12 19:35:52 +02:00
Daniel Stolt
6fe3cf8538 Deleted unused element from layout editor. 2015-07-11 17:03:45 +01:00
Daniel Stolt
db6c25aba2 Added keyboard shortcut reference to layout editor. 2015-07-11 16:58:49 +01:00
yw80
938fd5b827 Delete the CamelFriendly function call to DisplayName.
The CamelFriendly function is designed for Technical Name. The
DisplayName needs to be displayed as it is.
2015-07-10 12:00:27 +08:00
Sébastien Ros
b100634587 Merge pull request #5486 from jersiovic/patch-4
Issue #5141 Retrieve/Store methods from InfoSet doesn't support char type
2015-07-09 13:00:10 -07:00
Sébastien Ros
a071f21f4e Merge pull request #5485 from jersiovic/patch-1
Issue #5061 GetImageProfileUrl reprocess images obtained through a dynamic profile on every restart 1.9.x pull request
2015-07-09 12:57:48 -07:00
Sébastien Ros
eed1a9a063 Merge pull request #5479 from dcinzona/patch-3
Fixes #5398 - ShellDescriptorCache in HostComponents
2015-07-09 12:57:20 -07:00
Sébastien Ros
0faaa22546 Merge pull request #5465 from qt1/IBN-Labs/Support-Guid-in--CreateColumn
Support CreateColumn<Guid>()
2015-07-09 12:32:29 -07:00
Sébastien Ros
0f6fa5844b Merge pull request #5442 from yw80/1.9.x
Fixed the items count in media library when modify the item size in css
2015-07-09 12:18:09 -07:00
Sipke Schoorstra
784e1c0961 Added web.config with redirect bindings. 2015-07-09 13:44:02 +01:00
Sipke Schoorstra
9a2eaf7ac9 #5489: Handling potential null value for MediaLibraryPickerField.MediaParts.
This happens when a content type has both a MediaLibraryPickerField and the LayoutPart attached.
The layout editor renders the field, whose shape template accesses the MediaParts property, which is not initialized for new content items.

Fixes #5489
2015-07-08 22:45:52 +01:00
Sergio Navarro
d805c7773d Fixed #5141 Retrieve & Store doesn't support char 2015-07-07 19:42:06 +02:00
Gustavo Tandeciarz
18c5b5dfff Fixes #5398 - ShellDescriptorCache in HostComponents
Added Orchard.Environment.Descriptor.ShellDescriptorCache setting back to HostComponents.config. For some reason, this was removed at some point but I believe it needs to be there for Azure Web Apps deployments (when running with a shared file system and multiple instances)

Original commit by @sebastienros
a2d91796d1
2015-07-06 10:14:10 -04:00
Gustavo Tandeciarz
b76306dfb3 Added mimeMaps to root web.config
I'm not sure that this is something that we want to include globally, but I have had some issues with the following mime maps on Azure.
Specifically, SVG files getting returned as binary, breaking embeds in media library, editors and UI (front and admin).

This may also be directly related to storing media files in azure blob storage (and setting the mimetype when uploading files to blob storage)
2015-07-06 08:14:08 -04:00
Lombiq
89c5b2f7de Fixing that Audit Trail summary item edit link was double-encoded 2015-07-06 01:15:12 +02:00
Sipke Schoorstra
6bce34f379 #5260: Fixed the issue where form validation result gets output cached.
Fixes #5260
2015-07-04 13:01:17 +02:00
Sipke Schoorstra
c8f2c27311 Fixed form redirect issue.
This fixes the issue where you would not stay on the same page after a model validation occurred.
2015-07-04 12:45:17 +02:00
Sipke Schoorstra
22fa33c06f #5279: Fixed "potentially dangerous request" error.
Fixes #5279
2015-07-04 12:25:23 +02:00
Sipke Schoorstra
2508f503b7 #5298: Suppressed input validation on SMPT test form.
This fixes the issue when you try and use address formats such as "User <user@domain.com>" and adds support for sending HTML as part of the message body.

Fixes #5298
2015-07-04 09:51:05 +02:00
Sipke Schoorstra
1093e16a81 #5452: Improved ContentItem and Projection elements by rendering an abstract representation instead.
Fixes #5452
2015-07-04 09:36:31 +02:00
Sipke Schoorstra
1fe436e05a Fixed incorrect method error. 2015-07-04 09:32:51 +02:00
Sipke Schoorstra
b18f153e6a #5445: Fixed form field binding issues.
This fixes two issues:
1. Adding a Form element (and selecting the content type to create using the submitted values) and then adding a form element would not cause the Bindings tab to appear.
2. Adding nested containers (such as Grid, Row and Column) to a Form element would prevent the Bindings tab from appearing when adding a form field element such as TextField to a nested container.

Work Item: #5445
2015-07-04 00:37:14 +02:00
Sipke Schoorstra
b05dcf9a56 Fixed default layout data for Form. 2015-07-02 15:40:54 +03:00
Sipke Schoorstra
3c7fffc320 Fixed that default layout data would not be applied.
This fixes the issue where the default layout data string would not be applied when creating new content items of a content type with the LayoutPart attached.
For example, creating new Form content items would start out with an empty canvas instead of with a default Form element and a submit button.
2015-07-02 15:34:08 +03:00
Sipke Schoorstra
b580995e4b Added "TypeName" to element data serialization black list.
Having the "TypeName" as part of the element's data field is redundant.
2015-07-02 15:30:20 +03:00
Sipke Schoorstra
2873eb8991 #5337: Fixed homepage becoming lost after publishing layout template being used by the homepage.
Work Item: 5337
2015-07-02 13:37:20 +03:00
Sipke Schoorstra
eebe29fec3 #5467: Fixes the issue where the "Set as homepage" setting is not retained when saving,
The issue was that when you save a content item (without publishing it) while checking the "Set as homepage" checkbox, it would lose its checked status after save.
With this change, the checkbox is again rendered but in a checked status, so that when you do publish, it will become the homepage.

Fixes #5467
2015-07-02 13:01:49 +03:00
qt1
7bbad86eb4 Support CreateColumn<Guid>() 2015-07-01 21:53:05 +03:00
Sébastien Ros
dbba4e2787 Merge pull request #5458 from dcinzona/patch-1
Update web.config MVC bindings for Azure Cloud Service
2015-07-01 07:46:39 -07:00
Sébastien Ros
27365a71d9 Merge pull request #5460 from dcinzona/patch-3
Web.Config: Orchard Layouts Updating MVC reference to 5.2.3
2015-07-01 07:46:20 -07:00
Sébastien Ros
6a5028b80a Merge pull request #5461 from dcinzona/patch-4
Web.config - Dynamic Forms: MVC reference updated to 5.2.3
2015-07-01 07:46:00 -07:00
Gustavo Tandeciarz
e021218b3c Updated bindings in azure cloud service web.config
Updated bindings for system.web.http and system.net.http.formatting to 5.2.3
2015-06-30 19:48:05 -04:00
Gustavo Tandeciarz
993e6a1e43 Web.config: MVC reference updated to 5.2.3
Was still referencing 5.1.0.0
2015-06-30 17:54:18 -04:00
Gustavo Tandeciarz
0318db4c53 Web.Config: Updating MVC reference to 5.2.3
web.config was still referencing 5.1.0.0
2015-06-30 17:53:13 -04:00
Sebastien Ros
03a193b6c2 Fixing compilation 2015-06-30 14:38:12 -07:00
Gustavo Tandeciarz
38705580c8 Update web.config MVC bindings
Updated from 5.2.0.0 to 5.2.3
2015-06-30 14:48:02 -04:00
Sebastien Ros
6b0985a44e Merge branch 'master' into 1.9.x 2015-06-30 11:31:35 -07:00
Sebastien Ros
2c3973bfa0 Merge branch '1.9.1' 2015-06-30 11:30:37 -07:00
Jasmin Savard
28168c0550 Fixes #5457; Admin Culture Picker cookie not working on localhost 2015-06-30 13:09:19 -04:00
Sipke Schoorstra
c3dffb79f5 #5378: Fixed content field elements placement for content picker field and media picker field. 2015-06-29 14:27:23 +03:00
Sipke Schoorstra
5b40567b6d #5407: Layout elements now evaluate tokens. 2015-06-29 14:01:58 +03:00
Sergio Navarro
0f48019321 Fixed bug addes on pull request 2015-06-28 01:11:06 +02:00
Sipke Schoorstra
583ff8951a Removed unused namespaces. 2015-06-27 19:49:23 +03:00
Sipke Schoorstra
5c688267fa #5420: Added stub CSS files for various activities to prevent 404 errors. 2015-06-27 18:47:06 +03:00
Sipke Schoorstra
2c496a36db #5437: Maintaining selected values after model validation error. 2015-06-27 18:31:08 +03:00
yw80
51a364a184 Fix the items count in media library when modify the item size in css
Item shape is square in the media library. If the item size in
orchard-medialibrary-admin.css modified for different width and height,
the count of items will be wrong.
2015-06-27 17:43:51 +08:00
Nicholas Mayne
c435a98670 Merge pull request #5435 from yw80/1.9.x
Remove a excess @ in TaxonomyField.cshtml
2015-06-26 09:07:23 +01:00
yw80
42dae3edf3 Remove a excess @ in TaxonomyField.cshtml
I think this is just an oversight.
2015-06-26 14:21:07 +08:00
Sergio Navarro
24ee246a34 Differentiator is ignored processing placement
In placement files shapeType uses "__" intead of '-' char for declaring a differenciator. The point is second one is used only in template files as can be seen in documentation http://docs.orchardproject.net/Documentation/Accessing-and-rendering-shapes#NamingShapesandTemplates
However GetShapeType looks for '-' character ignoring placements for a ShapeType with a differentiator. This produces strange behaviors and a lot of headaches to users because when they set for example: <Place Fields_Common_Text__SeoTitle="/Header:0"/>  in a placement file it forces all Fields_Common_Text shapes within the same Match to be rendered at Header:0 area instead of only affecting those with the SeoTitle differentiator.
2015-06-26 02:34:08 +02:00
Sergio Navarro
9966e13fa3 Removed FilterContext and extra read 2015-06-25 22:50:34 +02:00
Sébastien Ros
f3fc2b53ba Merge pull request #5429 from dalenewman/patch-2
Fix moderator notification
2015-06-25 13:20:16 -07:00
Sébastien Ros
1a9b7af4ac Merge pull request #5430 from jchenga/issues/5148-1.9.x
[Fixes #5418] Lost Password not working with Anonymous Access Off
2015-06-25 13:15:32 -07:00
Jack Cheng
0c7fd67dca [Fixes #5418] Lost Password not working with Anonymous Access Off 2015-06-25 12:57:09 -07:00
Dale Newman
6063ba31d0 Fix moderator notification
`Orchard.Email.Services.SmtpMessageChannel.Process` expects a string for Recipients, not a string array. This results in an *Object reference not set to an instance of an object* exception and the moderator(s) do not get notified. Fixes #4928.
2015-06-25 15:45:50 -04:00
Sébastien Ros
7bf2c702a1 Merge pull request #5427 from jersiovic/patch-2
#5426 Projections don't order queries following Position field
2015-06-25 12:41:42 -07:00
Sébastien Ros
61d432ba4c Merge pull request #5413 from dcinzona/patch-2
Assembly binding to azure storage 4.3.0
2015-06-25 12:23:20 -07:00
Sébastien Ros
7cdb9ecf53 Merge pull request #5404 from MpDzik/pr/localize-quote
Fix handling localized strings with quotes
2015-06-25 12:22:52 -07:00
Sergio Navarro
ae61c81575 #5426 Projections don't order queries following Position field
Projections don't order queries following the Position field of each order in the query

Related issue https://github.com/OrchardCMS/Orchard/issues/5426
2015-06-25 20:26:15 +02:00
Lombiq
e10ba8126a Fixing that ClientHostAddressAccessor failed in a background task
This was the case e.g. when roles were modified in a background task with Audit Trail trying to record the event
2015-06-25 00:35:21 +02:00
Lombiq
a7626b78f5 Fixing that instead of just widgets all content items were retrieved in some WidgetsService methods 2015-06-24 16:04:11 +02:00
Sergio Navarro
29042d10f2 Update ImageProfileManager.cs
Image cache is empty after every reboot of the Orchard app. It makey Dynamic ImageProfiles reprocess images after every reboot. It has a big impact on performance because all the images that use dynamic profiles are reprocessed when they are requested after a reboot. When you open a page with a number of images disks usage increases drammatically and the apps answer very slow to other requests

This is related with this issue https://github.com/OrchardCMS/Orchard/issues/5061
2015-06-23 23:05:17 +02:00
Sebastien Ros
760e30855c Updating version number 1.9.1 2015-06-23 11:20:06 -07:00
Marek Dzikiewicz
6636527006 Add unit tests for #4154 and #5402 2015-06-23 11:44:46 +02:00
Marek Dzikiewicz
aacf0b2476 Introduce ILocalizationStreamParser
This moves the logic of parsing PO files from
DefaultLocalizedStringManager to a separate service, so that parsing
can be tested independently from resolving translations from loaded PO
files.
2015-06-23 11:44:29 +02:00
Gustavo Tandeciarz
88ac0d2879 Assembly binding to azure storage 4.3.0
Retargeting to 1.9.x - updated assembly binding from 3.1.0 to 4.3.0
2015-06-22 18:55:35 -04:00
Sébastien Ros
ac305af963 Merge pull request #5406 from MpDzik/pr/media-import-loc
MediaLibrary - Fix localization of Import button
2015-06-22 15:45:46 -07:00
Sebastien Ros
78fb58f016 Fixing localization gender 2015-06-22 10:10:58 -07:00
Sebastien Ros
8481768b58 Fixing culture list encoding 2015-06-22 10:06:34 -07:00
Marek Dzikiewicz
50d65bc0b9 MediaLibrary - Fix localization of Import button 2015-06-21 17:42:54 +02:00
agriffard
4eb8d1d2ea Fix some typos #5405 2015-06-21 15:44:04 +02:00
Marek Dzikiewicz
104cf7d5f4 Fix handling localized strings with quotes 2015-06-20 22:42:33 +02:00
Daniel Stolt
220c1b591a Restored reset of markup content styling in layout editor. 2015-06-20 20:38:42 +03:00
Daniel Stolt
b06a4ecb73 #5403 Improved native clipboard support in layout editor. 2015-06-20 19:35:11 +03:00
Daniel Stolt
764db254da Made layout editor toolbox separately scrollable while in sticky mode. 2015-06-20 16:42:53 +03:00
Bertrand Le Roy
c1359f7a86 Add a heading element that renders as h1-h6 tags. 2015-06-19 18:57:45 -07:00
Sebastien Ros
51409346cc Fixing mismatched assembly versions 2015-06-19 12:57:19 -07:00
Sebastien Ros
2cd5af5193 Reverting IMembership usage in FormsAuthenticationService 2015-06-19 10:54:46 -07:00
Sebastien Ros
1180425109 Updating libraries 2015-06-19 10:39:00 -07:00
Sébastien Ros
3c3a6df6dd Merge pull request #5391 from paynecrl97/5390/delay_output_cache_key_creation
Defers output cache key creation until we know we need it
2015-06-19 09:35:10 -07:00
paynecrl97
c6e96867c7 Only executes itemDescriptor logic if Debug logging is enabled 2015-06-19 09:17:29 +01:00
Sebastien Ros
8d134ba0c5 Fixing html-encoding in WebSearch settings page 2015-06-18 16:47:38 -07:00
Sebastien Ros
9d5bc20666 Fixing unit tests 2015-06-18 14:19:44 -07:00
Sébastien Ros
1fcf7c86d0 Merge pull request #5371 from gcsuk/1.9.x
Improved Recipe Journal Logging Detail
2015-06-18 12:39:05 -07:00
Sébastien Ros
bca643bf1f Merge pull request #5292 from Hazzamanic/1.9.x
fixing placementeditor try/catch block
2015-06-18 12:28:00 -07:00
Sebastien Ros
f276501923 Merge branch 'sebros/authcookie' into 1.9.x 2015-06-18 10:31:57 -07:00
Sebastien Ros
76408da930 #5315: Adding new settings to configure SSL cookies
- Creating ISslSettingsProvider to define whether cookies can only be sent over SSL or not
- Implementing DefaultSslSettingsProvider based on Sites.config and web.config
making it configurable per tenant or for the whole site
- Implementing SecureSocketsLayerSettingsProvider in Orchard.SecureSocketsLayerSettingsProvider

Fixes 5315
2015-06-17 18:06:47 -07:00
Skrypt
43497c8093 Closes #5389; Admin Culture Picker wrong cookie domain. 2015-06-17 20:02:04 -04:00
paynecrl97
f13c9d47c7 Adds more detail to itemDescriptor 2015-06-17 16:05:53 +01:00
paynecrl97
1a8b17d04e Defers output cache key creation until we know we need it 2015-06-17 14:02:05 +01:00
Sebastien Ros
20c5b494cd By default, html-encode translation parameters
Also ensure that any existing parameter is not double-encoded by
removing .Text when used as a translation parameter.
2015-06-16 16:50:45 -07:00
Sebastien Ros
cd49d2ccf2 Updating ruleset location for all projects 2015-06-16 16:22:04 -07:00
Sebastien Ros
aa2e2cf1d0 Ignoring VS 2015 settings files 2015-06-16 11:16:35 -07:00
Bertrand Le Roy
8eea9a6771 Add missing reference to media library from image editor web config so that views compile properly. 2015-06-15 12:42:50 -07:00
Lombiq
1d445c5438 Fixing that Custom Forms didn't display a submit button text if there was none configured
The button text not being configured can happen on an 1.8 to 1.9 upgrade for example.
2015-06-15 00:07:01 +02:00
Lombiq
6aabc4d9f9 Fixing that the Audit Trail Recycle Bin caused YSOD if a content item didn't have a display text (like Comments) 2015-06-14 23:18:25 +02:00
Bertrand Le Roy
14172fec51 Fix compilation issue on dynamic forms admin views that use namespaces from layouts. 2015-06-13 16:42:09 -07:00
Sipke Schoorstra
9e88d16273 Added missing null check to Projection element driver's export method. 2015-06-13 19:11:25 +03:00
Lombiq
66af4a8cdf Adding null check for query string parameters in AuditTrail to prevent possible YSOD 2015-06-13 01:02:16 +02:00
Rob King
92bde1ac71 Merge pull request #2 from gcsuk/ImprovedRecipeJournal
Replaced string.format with Localizable T
2015-06-10 12:24:32 +01:00
Rob King
7e149c4bc1 Replaced string.format with Localizable T 2015-06-10 10:07:04 +01:00
Rob King
d78afaeb51 Merge pull request #1 from gcsuk/ImprovedRecipeJournal
Improved Recipe Journal Logging Detail
2015-06-09 16:09:53 +01:00
Rob King
a0279f2d9c Improved recipe logging to give a trail of executed tasks 2015-06-09 15:59:44 +01:00
Hazza
98475f7aa0 fixing placementeditor try/catch block 2015-05-16 16:34:20 +01:00
1426 changed files with 20783 additions and 33757 deletions

3
.deployment Normal file
View File

@@ -0,0 +1,3 @@
[config]
command = deploy.cmd
SCM_COMMAND_IDLE_TIMEOUT = 3600

15
.gitignore vendored
View File

@@ -96,6 +96,7 @@ publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
@@ -164,13 +165,14 @@ build/
/buildtasks
/artifacts
*.sln.cache
#src/Orchard.Web/Media/*
src/Orchard.Web/Media/*
log.xml
profiling/
*.orig
src/Orchard.Web/Modules-temp/*
src/Backup/*
src/packages/*
src/node_modules
src/UpgradeLog.*
*.itrace.csdef
*.build.csdef
@@ -182,14 +184,7 @@ src/Orchard.Web/Orchard.Web.Publish.xml
src/TestResults/*
src/Orchard.Web/Properties/PublishProfiles
src/Orchard.Azure/Orchard.Azure.CloudService/Staging/
node_modules/
# Enable all /lib artifacts
#enable all /lib artifacts
!lib/*/*.*
# Enable version control of some IDeliverable specifics.
src/Orchard.Web/Media/Default/RecipeJournal/*
src/Orchard.Web/Media/Default/_Profiles/*
# Enable "IDeliverable/Packaging/" folder.
!src/IDeliverable/Packaging/*/*.*
*/.vs/*

View File

@@ -27,6 +27,7 @@
<BuildPlatform Condition="$(ProgramW6432) != ''">x64</BuildPlatform>
<BuildPlatform Condition="$(BuildPlatform) == ''">x86</BuildPlatform>
<Configuration Condition="$(Configuration) == ''">Release</Configuration>
<!-- TeamCity build number -->
<Version>$(BUILD_NUMBER)</Version>
@@ -115,7 +116,7 @@
<MSBuild
Projects="$(SrcFolder)\Orchard.sln"
Targets="Build"
Properties="Configuration=Release;OutputPath=$(CompileFolder)" />
Properties="Configuration=$(Configuration);OutputPath=$(CompileFolder)" />
<!-- Compile to "regular" output folder for devs using VS locally -->
<MSBuild
Projects="$(SrcFolder)\Orchard.sln"
@@ -126,7 +127,7 @@
<MSBuild
Projects="$(SrcFolder)\Tools\MSBuild.Orchard.Tasks\MSBuild.Orchard.Tasks.csproj"
Targets="Build"
Properties="Configuration=Release;OutputPath=$(MsBuildTasksFolder)" />
Properties="Configuration=$(Configuration);OutputPath=$(MsBuildTasksFolder)" />
</Target>
<Target Name="TypeScript" DependsOnTargets="CompileMsBuildTasks">
@@ -273,19 +274,19 @@
<!-- extra processing of the staged config files -->
<TransformXml
Source="$(StageFolder)\Web.Config"
Transform="$(SrcFolder)\Orchard.Web\Web.Release.Config"
Transform="$(SrcFolder)\Orchard.Web\Web.$(Configuration).Config"
Destination="$(StageFolder)\Web.Config"
/>
<TransformXml
Source="$(StageFolder)\Config\HostComponents.Config"
Transform="$(SrcFolder)\Orchard.Web\Config\HostComponents.Release.Config"
Transform="$(SrcFolder)\Orchard.Web\Config\HostComponents.$(Configuration).Config"
Destination="$(StageFolder)\Config\HostComponents.Config"
/>
<TransformXml
Source="$(StageFolder)\Config\log4net.Config"
Transform="$(SrcFolder)\Orchard.Web\Config\log4net.Release.Config"
Transform="$(SrcFolder)\Orchard.Web\Config\log4net.$(Configuration).Config"
Destination="$(StageFolder)\Config\log4net.Config"
/>

View File

@@ -16,8 +16,8 @@ Our mission is to empower our users and foster a dedicated and diverse community
There are many ways you can [contribute to Orchard](http://orchardproject.net/contribution): you can [fix bugs](https://github.com/OrchardCMS/Orchard/issues), contribute modules and themes to [our gallery](http://gallery.orchardproject.net/), [write documentation](https://github.com/OrchardCMS/OrchardDoc), [translate Orchard](http://orchardproject.net/localize), or answer questions [on our forums](http://orchard.codeplex.com/discussions) and [on Stack Overflow](http://stackoverflow.com/questions/tagged/orchardcms).
## Project Status
Orchard is currently in version 1.8.1. We invite participation by the developer community in shaping the projects direction, so that we can publicly validate our designs and development approach.
Our 1.8.1 release is available from our Downloads page, and is easy to [Install Orchard using the Web Platform Installer](http://www.orchardproject.net/docs/Installing-Orchard.ashx). We encourage interested developers to check out the source code on the Orchard Github site and get involved with the project.
Orchard is currently in version 1.9.1. We invite participation by the developer community in shaping the projects direction, so that we can publicly validate our designs and development approach.
Our 1.9.1 release is available from our Downloads page, and is easy to [Install Orchard using the Web Platform Installer](http://www.orchardproject.net/docs/Installing-Orchard.ashx). We encourage interested developers to check out the source code on the Orchard Github site and get involved with the project.
* [Download the latest release](https://github.com/OrchardCMS/Orchard/releases)
* [Feature roadmap](http://www.orchardproject.net/docs/feature-roadmap.ashx)

114
deploy.cmd Normal file
View File

@@ -0,0 +1,114 @@
@if "%SCM_TRACE_LEVEL%" NEQ "4" @echo off
:: ----------------------
:: KUDU Deployment Script
:: Version: 0.1.11
:: ----------------------
:: Prerequisites
:: -------------
:: Verify node.js installed
where node 2>nul >nul
IF %ERRORLEVEL% NEQ 0 (
echo Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment.
goto error
)
:: Setup
:: -----
setlocal enabledelayedexpansion
SET ARTIFACTS=%~dp0%..\artifacts
IF NOT DEFINED DEPLOYMENT_SOURCE (
SET DEPLOYMENT_SOURCE=%~dp0%.
)
IF NOT DEFINED DEPLOYMENT_TARGET (
SET DEPLOYMENT_TARGET=%ARTIFACTS%\wwwroot
)
IF NOT DEFINED NEXT_MANIFEST_PATH (
SET NEXT_MANIFEST_PATH=%ARTIFACTS%\manifest
IF NOT DEFINED PREVIOUS_MANIFEST_PATH (
SET PREVIOUS_MANIFEST_PATH=%ARTIFACTS%\manifest
)
)
IF NOT DEFINED KUDU_SYNC_CMD (
:: Install kudu sync
echo Installing Kudu Sync
call npm install kudusync -g --silent
IF !ERRORLEVEL! NEQ 0 goto error
:: Locally just running "kuduSync" would also work
SET KUDU_SYNC_CMD=%appdata%\npm\kuduSync.cmd
)
IF NOT DEFINED DEPLOYMENT_TEMP (
SET DEPLOYMENT_TEMP=%temp%\___deployTemp%random%
SET CLEAN_LOCAL_DEPLOYMENT_TEMP=true
)
IF DEFINED CLEAN_LOCAL_DEPLOYMENT_TEMP (
IF EXIST "%DEPLOYMENT_TEMP%" rd /s /q "%DEPLOYMENT_TEMP%"
mkdir "%DEPLOYMENT_TEMP%"
)
IF NOT DEFINED MSBUILD_PATH (
SET MSBUILD_PATH=%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe
)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Deployment
:: ----------
echo Handling .NET Web Application deployment.
:: 1. Restore NuGet packages
IF /I "" NEQ "" (
call :ExecuteCmd nuget restore "%DEPLOYMENT_SOURCE%\"
IF !ERRORLEVEL! NEQ 0 goto error
)
:: 2. Build to the temporary path
call :ExecuteCmd "%MSBUILD_PATH%" "%DEPLOYMENT_SOURCE%\Orchard.proj" /t:Precompiled /v:m
IF !ERRORLEVEL! NEQ 0 goto error
:: 3. KuduSync
call :ExecuteCmd "%KUDU_SYNC_CMD%" -v 50 -f "%DEPLOYMENT_SOURCE%\build\Precompiled" -t "%DEPLOYMENT_TARGET%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.hg;.deployment;deploy.cmd"
IF !ERRORLEVEL! NEQ 0 goto error
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Post deployment stub
IF DEFINED POST_DEPLOYMENT_ACTION call "%POST_DEPLOYMENT_ACTION%"
IF !ERRORLEVEL! NEQ 0 goto error
goto end
:: Execute command routine that will echo out when error
:ExecuteCmd
setlocal
set _CMD_=%*
call %_CMD_%
if "%ERRORLEVEL%" NEQ "0" echo Failed exitCode=%ERRORLEVEL%, command=%_CMD_%
exit /b %ERRORLEVEL%
:error
endlocal
echo An error has occurred during web site deployment.
call :exitSetErrorLevel
call :exitFromFunction 2>nul
:exitSetErrorLevel
exit /b 1
:exitFromFunction
()
:end
endlocal
echo Finished successfully.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,9 @@
/**********************************************************************/
/* Install.SQL */
/* Creates a login and makes the user a member of db roles */
/* */
/* Modifications for SQL AZURE - ON MASTER */
/**********************************************************************/
CREATE LOGIN PlaceHolderForUser WITH PASSWORD = 'PlaceHolderForPassword'

View File

@@ -0,0 +1,15 @@
/**********************************************************************/
/* CreateUser.SQL */
/* Creates a user and makes the user a member of db roles */
/* This script runs against the User database and requires connection string */
/* Supports SQL Server and SQL AZURE */
/**********************************************************************/
-- Create database user and map to login
-- and add user to the datareader, datawriter, ddladmin and securityadmin roles
--
CREATE USER PlaceHolderForUser FOR LOGIN PlaceHolderForUser;
GO
EXEC sp_addrolemember 'db_owner', PlaceHolderForUser;
GO

View File

@@ -1,45 +0,0 @@
/**********************************************************************/
/* Install.SQL */
/* Creates a login and makes the user a member of db roles */
/* */
/**********************************************************************/
-- Declare variables for database name, username and password
DECLARE @dbName sysname,
@dbUser sysname,
@dbPwd nvarchar(max);
-- Set variables for database name, username and password
SET @dbName = 'PlaceHolderForDb';
SET @dbUser = 'PlaceHolderForUser';
SET @dbPwd = 'PlaceHolderForPassword';
DECLARE @cmd nvarchar(max)
-- Create login
IF( SUSER_SID(@dbUser) is null )
BEGIN
print '-- Creating login '
SET @cmd = N'CREATE LOGIN ' + quotename(@dbUser) + N' WITH PASSWORD ='''+ replace(@dbPwd, '''', '''''') + N''''
EXEC(@cmd)
END
-- Create database user and map to login
-- and add user to the datareader, datawriter, ddladmin and securityadmin roles
--
SET @cmd = N'USE ' + quotename(@DBName) + N';
IF( NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = ''' + replace(@dbUser, '''', '''''') + N'''))
BEGIN
print ''-- Creating user'';
CREATE USER ' + quotename(@dbUser) + N' FOR LOGIN ' + quotename(@dbUser) + N';
print ''-- Adding user'';
EXEC sp_addrolemember ''db_ddladmin'', ''' + replace(@dbUser, '''', '''''') + N''';
print ''-- Adding user'';
EXEC sp_addrolemember ''db_securityadmin'', ''' + replace(@dbUser, '''', '''''') + N''';
print ''-- Adding user'';
EXEC sp_addrolemember ''db_datareader'', ''' + replace(@dbUser, '''', '''''') + N''';
print ''-- Adding user'';
EXEC sp_addrolemember ''db_datawriter'', ''' + replace(@dbUser, '''', '''''') + N''';
END'
EXEC(@cmd)
GO

View File

@@ -1,7 +1,13 @@
<MSDeploy.iisApp>
<iisapp path="Orchard" managedRuntimeVersion="v4.0" />
<iisapp path="Orchard" managedRuntimeVersion="v4.0" />
<setAcl path="Orchard/App_Data" setAclAccess="Modify" />
<setAcl path="Orchard/Media" setAclAccess="Modify" />
<setAcl path="Orchard/bin/HostRestart" setAclAccess="Modify" />
<dbFullSql path="install.sql" />
</MSDeploy.iisApp>
<!-- Runs SQL script to create login and assign permissions, requires transacted="false"
This script runs as the database administrator provided in parameters.xml
-->
<dbfullsql path="createlogin.sql" transacted="false" />
<dbfullsql path="createuser.sql" transacted="false" />
</MSDeploy.iisApp>

View File

@@ -47,19 +47,17 @@
<!-- Prompts for the admin password and uses it for the administrator connection string.
This is use to create a login and assign permissions. The SQL tag indicates it is a parameter required for SQL.
The DbAdminPassword tag indicates it should be used when the user is creating a new database. If they're not, it can be filled in with the DbUserPassword value. -->
<parameter name="Database Administrator Password" description="Password for the database administrator account." tags="New, Password, SQL, dbAdminPassword">
<parameter name="Database Administrator Password" description="Password for the database administrator account." tags="Password, SQL, dbAdminPassword">
</parameter>
<parameter name="Admin Connection String SqlServer"
tags="SQLConnectionString, AdminConnectionString, Hidden, Validate" description="Automatically sets the connection string for the connection request."
defaultValue="Data Source={Database Server};Initial Catalog={Database Name};User Id={Database Administrator};Password={Database Administrator Password}">
<parameterEntry type="ProviderPath" scope="dbfullsql" match="install.sql" />
<parameter name="Admin Connection String SqlServer1" tags="SQLConnectionString, sql, Hidden" description="Automatically sets the connection string for the connection request." defaultValue="Data Source={Database Server};Initial Catalog=MASTER;User Id={Database Administrator};Password={Database Administrator Password}">
<parameterEntry type="ProviderPath" scope="dbfullsql" match="createlogin.sql" />
</parameter>
<parameter name="Non-Admin Connection String SqlServer"
tags="SQLConnectionString, UserConnectionString, Hidden" description="Automatically sets the connection string for the connection request."
defaultValue="Data Source={Database Server};Initial Catalog={Database Name};User Id={Database Username};Password={Database Password}">
<parameter name="Admin Connection String SqlServer2" tags="SQLConnectionString, SQL, Hidden" description="Automatically sets the connection string for the connection request." defaultValue="Data Source={Database Server};Initial Catalog={Database Name};User Id={Database Administrator};Password={Database Administrator Password}">
<parameterEntry type="ProviderPath" scope="dbfullsql" match="createuser.sql" />
</parameter>
<parameter name="Orchard Connection String" friendlyName="Orchard Connection String" description="Orchard SQL Data Connection String Setting" defaultValue="" tags="Sql, SqlCE, SingleLineConnectionString, Hidden">
<parameterEntry kind="TextFile" scope="\\Settings\.txt$" match="(?&lt;=\s*DataConnectionString:\s+)[^\s].*[^\r\n]" />

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

202
src/Gulpfile.js Normal file
View File

@@ -0,0 +1,202 @@
var glob = require("glob"),
path = require("path-posix"),
merge = require("merge-stream"),
gulpif = require("gulp-if"),
gulp = require("gulp"),
newer = require("gulp-newer"),
plumber = require("gulp-plumber"),
sourcemaps = require("gulp-sourcemaps"),
less = require("gulp-less"),
autoprefixer = require("gulp-autoprefixer"),
minify = require("gulp-minify-css"),
typescript = require("gulp-typescript"),
uglify = require("gulp-uglify"),
rename = require("gulp-rename"),
concat = require("gulp-concat"),
header = require("gulp-header"),
fs = require("fs");
/*
** GULP TASKS
*/
// Incremental build (each asset group is built only if one or more inputs are newer than the output).
gulp.task("build", function () {
var assetGroupTasks = getAssetGroups().map(function (assetGroup) {
var doRebuild = false;
return createAssetGroupTask(assetGroup, doRebuild);
});
return merge(assetGroupTasks);
});
// Full rebuild (all assets groups are built regardless of timestamps).
gulp.task("rebuild", function () {
var assetGroupTasks = getAssetGroups().map(function (assetGroup) {
var doRebuild = true;
return createAssetGroupTask(assetGroup, doRebuild);
});
return merge(assetGroupTasks);
});
// Set "Watchers" as sub-processes in order to restart the task when Assets.json changes.
gulp.task("watch", function () {
var watchers;
function restart() {
if (watchers) {
watchers.forEach(function (w) {
w.remove();
w.end();
});
}
watchers = [];
// Continuous watch (each asset group is built whenever one of its inputs changes).
getAssetGroups().forEach(function (assetGroup) {
var watchPaths = assetGroup.inputPaths.concat(assetGroup.watchPaths);
var watcher = gulp.watch(watchPaths, function (event) {
var isConcat = path.basename(assetGroup.outputFileName, path.extname(assetGroup.outputFileName)) !== "@";
if (isConcat)
console.log("Asset file '" + event.path + "' was " + event.type + ", rebuilding asset group with output '" + assetGroup.outputPath + "'.");
else
console.log("Asset file '" + event.path + "' was " + event.type + ", rebuilding asset group.");
var doRebuild = true;
var task = createAssetGroupTask(assetGroup, doRebuild);
});
watchers.push(watcher);
});
}
var p;
if (p) { p.exit(); }
p = gulp.watch("Orchard.Web/{Core,Modules,Themes}/*/Assets.json", function (event) {
console.log("Asset file '" + event.path + "' was " + event.type + ", resetting asset watchers.");
restart();
});
restart();
});
/*
** ASSET GROUPS
*/
function getAssetGroups() {
var assetManifestPaths = glob.sync("Orchard.Web/{Core,Modules,Themes}/*/Assets.json", {});
var assetGroups = [];
assetManifestPaths.forEach(function (assetManifestPath) {
var file = './' + assetManifestPath;
var json = fs.readFileSync(file, 'utf8');
assetManifest = eval(json);
assetManifest.forEach(function (assetGroup) {
resolveAssetGroupPaths(assetGroup, assetManifestPath);
assetGroups.push(assetGroup);
});
});
return assetGroups;
}
function resolveAssetGroupPaths(assetGroup, assetManifestPath) {
assetGroup.basePath = path.dirname(assetManifestPath);
assetGroup.inputPaths = assetGroup.inputs.map(function (inputPath) {
return path.resolve(path.join(assetGroup.basePath, inputPath));
});
assetGroup.watchPaths = [];
if (!!assetGroup.watch) {
assetGroup.watchPaths = assetGroup.watch.map(function (watchPath) {
return path.resolve(path.join(assetGroup.basePath, watchPath));
});
}
assetGroup.outputPath = path.resolve(path.join(assetGroup.basePath, assetGroup.output));
assetGroup.outputDir = path.dirname(assetGroup.outputPath);
assetGroup.outputFileName = path.basename(assetGroup.output);
}
function createAssetGroupTask(assetGroup, doRebuild) {
var outputExt = path.extname(assetGroup.output).toLowerCase();
switch (outputExt) {
case ".css":
return buildCssPipeline(assetGroup, doRebuild);
case ".js":
return buildJsPipeline(assetGroup, doRebuild);
}
}
/*
** PROCESSING PIPELINES
*/
function buildCssPipeline(assetGroup, doRebuild) {
assetGroup.inputPaths.forEach(function (inputPath) {
var ext = path.extname(inputPath).toLowerCase();
if (ext !== ".less" && ext !== ".css")
throw "Input file '" + inputPath + "' is not of a valid type for output file '" + assetGroup.outputPath + "'.";
});
var doConcat = path.basename(assetGroup.outputFileName, ".css") !== "@";
var generateSourceMaps = assetGroup.hasOwnProperty("generateSourceMaps") ? assetGroup.generateSourceMaps : true;
return gulp.src(assetGroup.inputPaths)
.pipe(gulpif(!doRebuild,
gulpif(doConcat,
newer(assetGroup.outputPath),
newer({
dest: assetGroup.outputDir,
ext: ".css"
}))))
.pipe(plumber())
.pipe(gulpif(generateSourceMaps, sourcemaps.init()))
.pipe(gulpif("*.less", less()))
.pipe(gulpif(doConcat, concat(assetGroup.outputFileName)))
.pipe(autoprefixer({ browsers: ["last 2 versions"] }))
// TODO: Start using below whenever gulp-header supports sourcemaps.
//.pipe(header(
// "/*\n" +
// "** NOTE: This file is generated by Gulp compilation and should not be edited directly!\n" +
// "** Any changes made directly to this file will be overwritten next time the Gulp compilation runs.\n" +
// "** For more information, see the Readme.txt file in the Gulp solution folder.\n" +
// "*/\n\n"))
.pipe(gulpif(generateSourceMaps, sourcemaps.write()))
.pipe(gulp.dest(assetGroup.outputDir))
.pipe(minify())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(assetGroup.outputDir));
}
function buildJsPipeline(assetGroup, doRebuild) {
assetGroup.inputPaths.forEach(function (inputPath) {
var ext = path.extname(inputPath).toLowerCase();
if (ext !== ".ts" && ext !== ".js")
throw "Input file '" + inputPath + "' is not of a valid type for output file '" + assetGroup.outputPath + "'.";
});
var doConcat = path.basename(assetGroup.outputFileName, ".js") !== "@";
var generateSourceMaps = assetGroup.hasOwnProperty("generateSourceMaps") ? assetGroup.generateSourceMaps : true;
return gulp.src(assetGroup.inputPaths)
.pipe(gulpif(!doRebuild,
gulpif(doConcat,
newer(assetGroup.outputPath),
newer({
dest: assetGroup.outputDir,
ext: ".js"
}))))
.pipe(plumber())
.pipe(gulpif(generateSourceMaps, sourcemaps.init()))
.pipe(gulpif("*.ts", typescript({
declaration: false,
//noImplicitAny: true,
noEmitOnError: true,
sortOutput: true,
}).js))
.pipe(gulpif(doConcat, concat(assetGroup.outputFileName)))
// TODO: Start using below whenever gulp-header supports sourcemaps.
//.pipe(header(
// "/*\n" +
// "** NOTE: This file is generated by Gulp compilation and should not be edited directly!\n" +
// "** Any changes made directly to this file will be overwritten next time the Gulp compilation runs.\n" +
// "** For more information, see the Readme.txt file in the Gulp solution folder.\n" +
// "*/\n\n"))
.pipe(gulpif(generateSourceMaps, sourcemaps.write()))
.pipe(gulp.dest(assetGroup.outputDir))
.pipe(uglify())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(assetGroup.outputDir));
}

View File

@@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{F1467A6B-2397-447B-BE90-766D192EC3D9}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IDeliverable.Licensing.Orchard</RootNamespace>
<AssemblyName>IDeliverable.Licensing.Orchard</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\autofac\Autofac.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\lib\newtonsoft.json\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\aspnetwebapi\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ILicensedProductManifest.cs" />
<Compile Include="LicenseValidationControllerBase.cs" />
<Compile Include="LicenseValidationErrorBannerBase.cs" />
<Compile Include="LicenseValidationHelper.cs" />
<Compile Include="LicenseVerificationTokenStore.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="LicenseSettingsPartHandlerBase.cs" />
<Compile Include="LicenseSettingsPartBase.cs" />
<Compile Include="LicenseSettingsPartDriverBase.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IDeliverable.Licensing\IDeliverable.Licensing.csproj">
<Project>{7e439cb7-1ace-435f-a8f3-5bb929423e34}</Project>
<Name>IDeliverable.Licensing</Name>
</ProjectReference>
<ProjectReference Include="..\..\Orchard\Orchard.Framework.csproj">
<Project>{2d1d92bb-4555-4cbe-8d0e-63563d6ce4c6}</Project>
<Name>Orchard.Framework</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -1,14 +0,0 @@
using Orchard;
using Orchard.Logging;
namespace IDeliverable.Licensing.Orchard
{
public interface ILicensedProductManifest : IDependency
{
string ProductId { get; }
string ProductName { get; }
bool SkipValidationForLocalRequests { get; }
string LicenseKey { get; }
ILogger Logger { get; }
}
}

View File

@@ -1,13 +0,0 @@
using Orchard.ContentManagement;
namespace IDeliverable.Licensing.Orchard
{
public abstract class LicenseSettingsPartBase : ContentPart
{
public string LicenseKey
{
get { return this.Retrieve(x => x.LicenseKey); }
set { this.Store(x => x.LicenseKey, value); }
}
}
}

View File

@@ -1,25 +0,0 @@
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
namespace IDeliverable.Licensing.Orchard
{
public abstract class LicenseSettingsPartDriverBase<TPart> : ContentPartDriver<TPart> where TPart : LicenseSettingsPartBase, new()
{
protected abstract string EditorShapeName { get; }
protected abstract string EditorShapeTemplateName { get; }
protected override DriverResult Editor(TPart part, dynamic shapeHelper)
{
return Editor(part, null, shapeHelper);
}
protected override DriverResult Editor(TPart part, IUpdateModel updater, dynamic shapeHelper)
{
return ContentShape(EditorShapeName, () =>
{
updater?.TryUpdateModel(part, Prefix, null, null);
return shapeHelper.EditorTemplate(TemplateName: EditorShapeTemplateName, Prefix: Prefix, Model: part);
}).OnGroup("Licenses");
}
}
}

View File

@@ -1,17 +0,0 @@
using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers;
using Orchard.Localization;
namespace IDeliverable.Licensing.Orchard
{
public abstract class LicenseSettingsPartHandlerBase<TPart> : ContentHandler where TPart : LicenseSettingsPartBase, new()
{
protected LicenseSettingsPartHandlerBase()
{
Filters.Add(new ActivatingFilter<TPart>("Site"));
OnGetContentItemMetadata<TPart>((context, part) => context.Metadata.EditorGroupInfo.Add(new GroupInfo(T("Licenses"))));
}
public Localizer T { get; set; } = NullLocalizer.Instance;
}
}

View File

@@ -1,31 +0,0 @@
using System.Web.Mvc;
using Orchard.Localization;
using Orchard.UI.Notify;
using Orchard.Utility.Extensions;
namespace IDeliverable.Licensing.Orchard
{
public abstract class LicenseValidationControllerBase : Controller
{
protected LicenseValidationControllerBase(INotifier notifier)
{
Notifier = notifier;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
protected INotifier Notifier { get; }
protected abstract string ProductId { get; }
public ActionResult VerifyLicenseKey()
{
LicenseValidationHelper.Instance.ClearLicenseValidationResult(ProductId);
if (LicenseValidationHelper.GetLicenseIsValid(ProductId))
Notifier.Information(T("License key succesfully validated."));
var urlReferrer = Request.UrlReferrer?.ToString();
return Redirect(Request.IsLocalUrl(urlReferrer) ? urlReferrer : "~/");
}
}
}

View File

@@ -1,71 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using IDeliverable.Licensing.Validation;
using Orchard;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.UI.Admin.Notification;
using Orchard.UI.Notify;
namespace IDeliverable.Licensing.Orchard
{
public abstract class LicenseValidationErrorBannerBase : Component, INotificationProvider
{
protected LicenseValidationErrorBannerBase(IEnumerable<ILicensedProductManifest> products, UrlHelper urlHelper, string productId)
{
mProducts = products;
mUrlHelper = urlHelper;
mProductId = productId;
}
private readonly IEnumerable<ILicensedProductManifest> mProducts;
private readonly UrlHelper mUrlHelper;
private readonly string mProductId;
public IEnumerable<NotifyEntry> GetNotifications()
{
var productManifest = mProducts.Single(x => x.ProductId == mProductId);
var licenseSettingsUrl = mUrlHelper.Action("Index", "Admin", new { area = "Settings", groupInfoId = "Licenses" });
var retryResultUrl = mUrlHelper.Action("VerifyLicenseKey", "LicenseValidation", new { area = productManifest.ProductName });
var retryResultLink = T("<a href=\"{0}\">Try again</a>", retryResultUrl);
LocalizedString message = null;
try
{
LicenseValidationHelper.EnsureLicenseIsValid(productManifest.ProductId);
}
catch (LicenseValidationException ex)
{
switch (ex.Error)
{
case LicenseValidationError.UnknownLicenseKey:
message = T("The <a href=\"{0}\">configured license key</a> for the {1} module is invalid. {2}", licenseSettingsUrl, productManifest.ProductName, retryResultLink);
break;
case LicenseValidationError.HostnameMismatch:
message = T("The <a href=\"{0}\">configured license key</a> for the {1} module is invalid for the current host name. {2}", licenseSettingsUrl, productManifest.ProductName, retryResultLink);
break;
case LicenseValidationError.NoActiveSubscription:
message = T("The <a href=\"{0}\">configured license key</a> for the {1} module has no active subscription. {2}", licenseSettingsUrl, productManifest.ProductName, retryResultLink);
break;
case LicenseValidationError.LicenseRevoked:
message = T("The <a href=\"{0}\">configured license key</a> for the {1} module has been revoked. {2}", licenseSettingsUrl, productManifest.ProductName, retryResultLink);
break;
case LicenseValidationError.TokenAgeValidationFailed:
case LicenseValidationError.TokenSignatureValidationFailed:
case LicenseValidationError.LicensingServiceError:
case LicenseValidationError.LicensingServiceUnreachable:
case LicenseValidationError.UnexpectedError:
default:
message = T("There was an error validating the <a href=\"{0}\">configured license key</a> for the {1} module. {2}", licenseSettingsUrl, productManifest.ProductName, retryResultLink);
break;
}
Logger.Warning(ex, "An error occurred while validating the configured license key for the {0} module. {1}", productManifest.ProductName, retryResultLink);
}
if (message != null)
yield return new NotifyEntry { Message = message, Type = NotifyType.Warning };
}
}
}

View File

@@ -1,112 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using IDeliverable.Licensing.Validation;
using IDeliverable.Licensing.VerificationTokens;
using Orchard;
using Orchard.Logging;
using Orchard.FileSystems.AppData;
namespace IDeliverable.Licensing.Orchard
{
public class LicenseValidationHelper
{
public static bool GetLicenseIsValid(string productId)
{
try
{
EnsureLicenseIsValid(productId);
return true;
}
catch
{
return false;
}
}
public static void EnsureLicenseIsValid(string productId)
{
Instance.ValidateLicense(productId);
}
public static LicenseValidationHelper Instance
{
get
{
var workContext = HttpContext.Current.Request.RequestContext.GetWorkContext();
var products = workContext.Resolve<IEnumerable<ILicensedProductManifest>>();
var appDataFolder = workContext.Resolve<IAppDataFolder>();
var instance = new LicenseValidationHelper(products, appDataFolder);
return instance;
}
}
private static readonly TimeSpan _validationResultCachedFor = TimeSpan.FromMinutes(5);
public LicenseValidationHelper(IEnumerable<ILicensedProductManifest> products, IAppDataFolder appDataFolder)
{
var tokenStore = new LicenseVerificationTokenStore(appDataFolder);
var tokenAccessor = new LicenseVerificationTokenAccessor(tokenStore);
mProducts = products;
mLicenseValidator = new LicenseValidator(tokenAccessor);
mCacheService = new CacheService();
}
private readonly IEnumerable<ILicensedProductManifest> mProducts;
private readonly LicenseValidator mLicenseValidator;
private readonly CacheService mCacheService;
public void ValidateLicense(string productId)
{
var productManifest = GetLicensedProductManifest(productId);
productManifest.Logger.Debug("Validating license for product '{0}'...", productId);
try
{
var cacheKey = ComputeCacheKey(productManifest);
mCacheService.GetValue(cacheKey, context =>
{
context.ValidFor = _validationResultCachedFor;
var options = LicenseValidationOptions.Default;
if (productManifest.SkipValidationForLocalRequests)
options = options | LicenseValidationOptions.SkipForLocalRequests;
productManifest.Logger.Debug("Validation result not in cache. Invoking the license validator for product '{0}'...", productId);
mLicenseValidator.ValidateLicense(productManifest.ProductId, productManifest.LicenseKey, options);
return true;
});
productManifest.Logger.Debug("License successfully validated for product '{0}'.", productId);
}
catch (Exception ex)
{
productManifest.Logger.Error(ex, "An error occurred while validating the license for product '{0}'.", productId);
throw;
}
}
public void ClearLicenseValidationResult(string productId)
{
var productManifest = GetLicensedProductManifest(productId);
productManifest.Logger.Debug("Clearing license validation result for product '{0}'...", productId);
var cacheKey = ComputeCacheKey(productManifest);
mCacheService.RemoveValue(cacheKey);
}
private ILicensedProductManifest GetLicensedProductManifest(string productId)
{
return mProducts.Single(x => x.ProductId == productId);
}
private string ComputeCacheKey(ILicensedProductManifest productManifest)
{
return $"ValidateLicenseResult-{productManifest.ProductId}-{productManifest.LicenseKey}-{productManifest.SkipValidationForLocalRequests}";
}
}
}

View File

@@ -1,63 +0,0 @@
using System;
using IDeliverable.Licensing.VerificationTokens;
using Orchard.FileSystems.AppData;
using Orchard.Logging;
namespace IDeliverable.Licensing.Orchard
{
internal class LicenseVerificationTokenStore : ILicenseVerificationTokenStore
{
public LicenseVerificationTokenStore(IAppDataFolder appDataFolder)
{
mAppDataFolder = appDataFolder;
}
private readonly IAppDataFolder mAppDataFolder;
public LicenseVerificationToken Load(string productId)
{
var path = GetRelativeTokenFilePath(productId);
if (!mAppDataFolder.FileExists(path))
return null;
LicenseVerificationToken token = null;
var tokenBase64 = mAppDataFolder.ReadFile(path);
try
{
token = LicenseVerificationToken.FromBase64(tokenBase64);
}
catch
{
// An exception while parsing the token indicates somebody probably
// tampered with it or it got corrupted. In this case, let's clear out
// the store and return nothing.
Clear(productId);
}
return token;
}
public void Save(string productId, LicenseVerificationToken token)
{
Clear(productId);
var path = GetRelativeTokenFilePath(productId);
var tokenBase64 = token.ToBase64();
mAppDataFolder.CreateFile(path, tokenBase64);
}
public void Clear(string productId)
{
var path = GetRelativeTokenFilePath(productId);
if (mAppDataFolder.FileExists(path))
mAppDataFolder.DeleteFile(path);
}
private string GetRelativeTokenFilePath(string productId)
{
return $"IDeliverable.Licensing/{productId}.lic";
}
}
}

View File

@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IDeliverable.Licensing.Orchard.Orchard")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IDeliverable.Licensing.Orchard.Orchard")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f1467a6b-2397-447b-be90-766d192ec3d9")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,40 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace IDeliverable.Licensing.Service
{
internal class ApiKeyAuthorizationAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
var values = new List<string>();
var paramsQuery =
from param in actionContext.Request.GetQueryNameValuePairs()
where String.Equals(param.Key, "ApiKey", StringComparison.OrdinalIgnoreCase)
select param.Value;
values.AddRange(paramsQuery.ToArray());
IEnumerable<string> headers;
actionContext.Request.Headers.TryGetValues("ApiKey", out headers);
if (headers != null)
values.AddRange(headers);
string apiKey = values != null ? values.FirstOrDefault() : null;
if (String.IsNullOrWhiteSpace(apiKey))
actionContext.Response = actionContext.ControllerContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
var expectedApiKey = ConfigurationManager.AppSettings["ApiKey"];
if (apiKey != expectedApiKey)
actionContext.Response = actionContext.ControllerContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.Web.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace IDeliverable.Licensing.Service
{
internal static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
ConfigSerializationSettings(config);
config.MapHttpAttributeRoutes();
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
}
private static void ConfigSerializationSettings(HttpConfiguration config)
{
var jsonSetting = new JsonSerializerSettings();
jsonSetting.Converters.Add(new StringEnumConverter());
config.Formatters.JsonFormatter.SerializerSettings = jsonSetting;
}
}
}

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
<!--
Learn more about Application Insights configuration with ApplicationInsights.config here:
http://go.microsoft.com/fwlink/?LinkID=513840
-->
<TelemetryModules>
<Add Type="Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.DiagnosticsTelemetryModule, Microsoft.ApplicationInsights" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCollector.PerformanceCollectorModule, Microsoft.ApplicationInsights.Extensibility.PerfCollector">
<!--
Use the following syntax here to collect additional performance counters:
<Counters>
<Add PerformanceCounter="\Process(??APP_WIN32_PROC??)\Handle Count" ReportAs="Process handle count" />
...
</Counters>
PerformanceCounter must be either \CategoryName(InstanceName)\CounterName or \CategoryName\CounterName
Counter names may only contain letters, round brackets, forward slashes, hyphens, underscores, spaces and dots.
You may provide an optional ReportAs attribute which will be used as the metric name when reporting counter data.
For the purposes of reporting, metric names will be sanitized by removing all invalid characters from the resulting metric name.
The following placeholders are supported as InstanceName:
??APP_WIN32_PROC?? - instance name of the application process for Win32 counters.
??APP_W3SVC_PROC?? - instance name of the application IIS worker process for IIS/ASP.NET counters.
??APP_CLR_PROC?? - instance name of the application CLR process for .NET counters.
-->
</Add>
<Add Type="Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry.RemoteDependencyModule, Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryModules.WebApplicationLifecycleModule, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryModules.WebRequestTrackingTelemetryModule, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryModules.WebExceptionTrackingTelemetryModule, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryModules.WebSessionTrackingTelemetryModule, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryModules.WebUserTrackingTelemetryModule, Microsoft.ApplicationInsights.Extensibility.Web" />
</TelemetryModules>
<TelemetryChannel Type="Microsoft.ApplicationInsights.Channel.PersistenceChannel, Microsoft.ApplicationInsights.PersistenceChannel" />
<ContextInitializers>
<Add Type="Microsoft.ApplicationInsights.Extensibility.BuildInfoConfigComponentVersionContextInitializer, Microsoft.ApplicationInsights" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.DeviceContextInitializer, Microsoft.ApplicationInsights" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.ContextInitializers.AzureRoleEnvironmentContextInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.ContextInitializers.DomainNameRoleInstanceContextInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
</ContextInitializers>
<TelemetryInitializers>
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebSyntheticTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebClientIpHeaderTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebUserAgentTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebOperationNameTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebOperationIdTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebUserTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebSessionTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
</TelemetryInitializers>
</ApplicationInsights>

View File

@@ -1,89 +0,0 @@
using System;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using IDeliverable.Licensing.Exceptions;
using IDeliverable.Licensing.Service.Services;
using IDeliverable.Licensing.VerificationTokens;
namespace IDeliverable.Licensing.Service.Controllers
{
[RoutePrefix("api/v1")]
public class LicenseController : ApiController
{
[HttpGet]
[Route("license/{licenseKey}/verify")]
[ApiKeyAuthorization]
public LicenseVerificationToken Verify(string licenseKey, string productId, string hostname)
{
var service = GetLicenseService();
try
{
return service.VerifyLicense(licenseKey, productId, hostname, throwOnError: false);
}
catch (LicenseVerificationException ex)
{
switch (ex.Error)
{
case LicenseVerificationError.UnknownLicenseKey:
ThrowHttpResponseException(ex, HttpStatusCode.NotFound);
break;
case LicenseVerificationError.HostnameMismatch:
ThrowHttpResponseException(ex, HttpStatusCode.Forbidden);
break;
case LicenseVerificationError.NoActiveSubscription:
case LicenseVerificationError.LicenseRevoked:
ThrowHttpResponseException(ex, HttpStatusCode.Gone);
break;
default:
throw;
}
}
return null;
}
[HttpGet]
[Route("test")]
[ApiKeyAuthorization]
public HttpResponseMessage Test()
{
var testKey = ConfigurationManager.AppSettings["TestKey"];
var testProductId = ConfigurationManager.AppSettings["TestProductId"];
var testHostname = ConfigurationManager.AppSettings["TestHostname"];
var service = GetLicenseService();
try
{
service.VerifyLicense(testKey, testProductId, testHostname, throwOnError: true);
}
catch (Exception ex)
{
return new HttpResponseMessage(HttpStatusCode.InternalServerError) { ReasonPhrase = $"Verification for a supposedly valid license failed: {ex.Message}." };
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
private static LicenseService GetLicenseService()
{
var sendOwlApiEndpoint = ConfigurationManager.AppSettings["SendOwlApiEndpoint"];
var sendOwlApiKey = ConfigurationManager.AppSettings["SendOwlApiKey"];
var sendOwlApiSecret = ConfigurationManager.AppSettings["SendOwlApiSecret"];
var tokenSigningCertificateThumbprint = ConfigurationManager.AppSettings["TokenSigningCertificateThumbprint"];
return new LicenseService(sendOwlApiEndpoint, sendOwlApiKey, sendOwlApiSecret, tokenSigningCertificateThumbprint);
}
private static void ThrowHttpResponseException(LicenseVerificationException ex, HttpStatusCode httpStatusCode)
{
var response = new HttpResponseMessage(httpStatusCode) { ReasonPhrase = ex.Message };
response.Headers.Add("LicensingErrorCode", ex.Error.ToString());
throw new HttpResponseException(response);
}
}
}

View File

@@ -1 +0,0 @@
<%@ Application Codebehind="Global.asax.cs" Inherits="IDeliverable.Licensing.Service.WebApiApplication" Language="C#" %>

View File

@@ -1,22 +0,0 @@
using System;
using System.Configuration;
using System.Web.Http;
using Microsoft.ApplicationInsights.Extensibility;
namespace IDeliverable.Licensing.Service
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
// Configure ApplicationInsights instrumentation key.
var instrumentationKey = ConfigurationManager.AppSettings["ApplicationInsights.InstrumentationKey"];
if (!String.IsNullOrWhiteSpace(instrumentationKey))
TelemetryConfiguration.Active.InstrumentationKey = instrumentationKey;
else
TelemetryConfiguration.Active.DisableTelemetry = true;
}
}
}

View File

@@ -1,251 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{6014E7AC-C979-4D50-B8D9-5FD9DC8CA641}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IDeliverable.Licensing.Service</RootNamespace>
<AssemblyName>IDeliverable.Licensing.Service</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>true</UseIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile>true</UseGlobalApplicationHostFile>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<ApplicationInsightsResourceId>/subscriptions/1788357e-d506-4118-9f88-092c1dcddc16/resourcegroups/Internal/providers/microsoft.insights/components/ideliverable-licensing</ApplicationInsightsResourceId>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="LogentriesCore, Version=2.6.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\logentries.core.2.7.0\lib\net40\LogentriesCore.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="LogentriesLog4net, Version=2.6.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\logentries.log4net.2.7.0\lib\net40\LogentriesLog4net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ApplicationInsights, Version=0.14.3.177, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.0.14.3-build00177\lib\net40\Microsoft.ApplicationInsights.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ApplicationInsights.Extensibility.PerfCollector, Version=0.14.3.185, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.PerformanceCollector.0.14.3-build00177\lib\net40\Microsoft.ApplicationInsights.Extensibility.PerfCollector.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry, Version=0.14.3.177, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.RuntimeTelemetry.0.14.3-build00177\lib\net45\Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ApplicationInsights.Extensibility.Web, Version=0.14.3.177, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.Web.0.14.3-build00177\lib\net45\Microsoft.ApplicationInsights.Extensibility.Web.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ApplicationInsights.PersistenceChannel, Version=0.14.3.186, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.PersistenceChannel.0.14.3-build00177\lib\net40\Microsoft.ApplicationInsights.PersistenceChannel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Diagnostics.Instrumentation.Extensions.Intercept, Version=0.14.0.8007, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.0.14.0-build08008\lib\net40\Microsoft.Diagnostics.Instrumentation.Extensions.Intercept.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Diagnostics.Tracing.EventSource, Version=1.1.16.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.16-beta\lib\net45\Microsoft.Diagnostics.Tracing.EventSource.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure">
<HintPath>..\..\..\lib\aspnetmvc\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Configuration, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.WindowsAzure.ConfigurationManager.3.1.0\lib\net40\Microsoft.WindowsAzure.Configuration.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\lib\newtonsoft.json\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net" />
<Reference Include="System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Web.Helpers">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=4.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor">
<HintPath>..\..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Routing" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Net.Http">
</Reference>
<Reference Include="System.Net.Http.WebRequest">
</Reference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Compile Include="App_Start\WebApiConfig.cs" />
<Compile Include="ApiKeyAuthorizationAttribute.cs" />
<Compile Include="Controllers\LicenseController.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\LicenseInfo.cs" />
<Compile Include="Services\LicenseService.cs" />
<Compile Include="Services\Logger.cs" />
<Compile Include="Services\OrderInfo.cs" />
<Compile Include="Services\OrderStatus.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Global.asax" />
<Content Include="packages.config" />
<Content Include="ApplicationInsights.config" />
<Content Include="Log4net.config" />
<None Include="Properties\PublishProfiles\ideliverable-licensing.pubxml" />
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IDeliverable.Licensing\IDeliverable.Licensing.csproj">
<Project>{7e439cb7-1ace-435f-a8f3-5bb929423e34}</Project>
<Name>IDeliverable.Licensing</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>56979</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:56979/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<Import Project="..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Error Condition="!Exists('..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<Import Project="..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.16-beta\build\portable-net45+win8+wpa81\Microsoft.Diagnostics.Tracing.EventSource.Redist.targets" Condition="Exists('..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.16-beta\build\portable-net45+win8+wpa81\Microsoft.Diagnostics.Tracing.EventSource.Redist.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.16-beta\build\portable-net45+win8+wpa81\Microsoft.Diagnostics.Tracing.EventSource.Redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.16-beta\build\portable-net45+win8+wpa81\Microsoft.Diagnostics.Tracing.EventSource.Redist.targets'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.0.14.0-build08008\build\Microsoft.ApplicationInsights.Agent.Intercept.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.0.14.0-build08008\build\Microsoft.ApplicationInsights.Agent.Intercept.targets'))" />
</Target>
<Import Project="..\..\packages\Microsoft.ApplicationInsights.0.14.3-build00177\tools\net40\Microsoft.ApplicationInsights.targets" Condition="Exists('..\..\packages\Microsoft.ApplicationInsights.0.14.3-build00177\tools\net40\Microsoft.ApplicationInsights.targets')" />
<Target Name="EnsureApplicationInsightsImported" BeforeTargets="BeforeBuild" Condition="'$(ApplicationInsightsImported)' == ''">
<Error Condition="!Exists('..\..\packages\Microsoft.ApplicationInsights.0.14.3-build00177\tools\net40\Microsoft.ApplicationInsights.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." />
<Error Condition="Exists('..\..\packages\Microsoft.ApplicationInsights.0.14.3-build00177\tools\net40\Microsoft.ApplicationInsights.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." />
</Target>
<Import Project="..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.0.14.0-build08008\build\Microsoft.ApplicationInsights.Agent.Intercept.targets" Condition="Exists('..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.0.14.0-build08008\build\Microsoft.ApplicationInsights.Agent.Intercept.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target> -->
</Project>

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<root>
<!-- Value of level may be ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF -->
<level value="DEBUG" />
<appender-ref ref="DebuggerAppender" />
<appender-ref ref="LeAppender" />
</root>
<appender name="LeAppender" type="log4net.Appender.LogentriesAppender, LogentriesLog4net">
<!-- Credentials are read from appSettings. -->
<immediateFlush value="true" />
<debug value="true" />
<useHttpPut value="false" />
<useSsl value="false" />
<layout type="log4net.Layout.PatternLayout">
<!-- The below pattern has been carefully formatted and optimized to work well with the Logentries.com entry parser. For reference see https://logentries.com/doc/search/. -->
<param name="ConversionPattern" value="%d %logger %level% %m%n%exceptionSessionId='%aspnet-request{ASP.NET_SessionId}'; Username='%aspnet-request{AUTH_USER}'; ClientIpAddress='%aspnet-request{REMOTE_ADDR}'; ClientUserAgent='%aspnet-request{HTTP_USER_AGENT}'; ServerName='%aspnet-request{SERVER_NAME}'; RequestMethod='%aspnet-request{REQUEST_METHOD}'; RequestUrl='%aspnet-request{URL}'; RequestQueryString='%aspnet-request{QUERY_STRING}'; RequestCookies='%aspnet-request{HTTP_COOKIE}'; MachineName='%property{log4net:HostName}';%n" />
</layout>
</appender>
<appender name="DebuggerAppender" type="log4net.Appender.DebugAppender">
<immediateFlush value="true" />
<layout type="log4net.Layout.SimpleLayout" />
</appender>
</log4net>

View File

@@ -1,35 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IDeliverable.Licensing.Service")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IDeliverable.Licensing.Service")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c2a67b6c-4615-4ecf-bfc6-39bf0f975c1f")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<ADUsesOwinOrOpenIdConnect>False</ADUsesOwinOrOpenIdConnect>
<LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>http://ideliverable-licensing.azurewebsites.net</SiteUrlToLaunchAfterPublish>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<MSDeployServiceURL>ideliverable-licensing.scm.azurewebsites.net:443</MSDeployServiceURL>
<DeployIisAppPath>ideliverable-licensing</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>$ideliverable-licensing</UserName>
<_SavePWD>True</_SavePWD>
<_DestinationType>AzureWebSite</_DestinationType>
</PropertyGroup>
</Project>

View File

@@ -1,14 +0,0 @@
namespace IDeliverable.Licensing.Service.Services
{
internal class LicenseInfo
{
public LicenseInfo(string key, int orderId)
{
Key = key;
OrderId = orderId;
}
public string Key { get; }
public int OrderId { get; }
}
}

View File

@@ -1,167 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using IDeliverable.Licensing.Exceptions;
using IDeliverable.Licensing.VerificationTokens;
using Newtonsoft.Json.Linq;
namespace IDeliverable.Licensing.Service.Services
{
internal class LicenseService
{
public LicenseService(string sendOwlApiEndpoint, string sendOwlApiKey, string sendOwlApiSecret, string tokenSigningCertificateThumbprint)
{
mSendOwlApiEndpoint = sendOwlApiEndpoint;
mSendOwlApiKey = sendOwlApiKey;
mSendOwlApiSecret = sendOwlApiSecret;
mTokenSigningCertificateThumbprint = tokenSigningCertificateThumbprint;
mLogger = new Logger(nameof(LicenseService));
}
private readonly string mSendOwlApiEndpoint;
private readonly string mSendOwlApiKey;
private readonly string mSendOwlApiSecret;
private readonly string mTokenSigningCertificateThumbprint;
private readonly Logger mLogger;
public LicenseVerificationToken VerifyLicense(string licenseKey, string productId, string hostname, bool throwOnError)
{
mLogger.Info($"Starting license verification... LicenseKey={licenseKey}; ProductId={productId}; Hostname={hostname};");
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(mSendOwlApiEndpoint);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", CreateBasicAuthenticationToken(mSendOwlApiKey, mSendOwlApiSecret));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var licenses = ParseLicenseInfo(client.GetAsync($"products/{productId}/licenses/check_valid?key={licenseKey}").Result.Content.ReadAsStringAsync().Result).ToList();
if (!licenses.Any())
throw new LicenseVerificationException($"No license with key '{licenseKey}' was found.", LicenseVerificationError.UnknownLicenseKey);
var orderId = licenses.First(x => x.Key == licenseKey).OrderId;
var order = ParseOrderInfo(client.GetAsync($"orders/{orderId}").Result.Content.ReadAsStringAsync().Result);
if (!order.IsProductAccessAllowed)
{
if(order.SubscriptionId != null)
throw new LicenseVerificationException($"The license with key '{licenseKey}' is not associated with an active subscription.", LicenseVerificationError.NoActiveSubscription);
throw new LicenseVerificationException($"The license with key '{licenseKey}' has been revoked.", LicenseVerificationError.LicenseRevoked);
}
if (!order.Hostnames.Contains(hostname, StringComparer.OrdinalIgnoreCase))
throw new LicenseVerificationException($"The license with key '{licenseKey}' is not valid for the provided '{hostname}'. Valid hostnames are '{String.Join(",", order.Hostnames)}", LicenseVerificationError.HostnameMismatch);
}
}
catch (Exception ex) when (!(ex is LicenseVerificationException))
{
mLogger.Error($"An error occurred while verifying license with SendOwl. LicenseKey={licenseKey}; ProductId={productId}; Hostname={hostname};", ex);
if (throwOnError)
throw;
mLogger.Info("Ignoring error and issuing verification token anyway. LicenseKey={licenseKey}; ProductId={productId}; Hostname={hostname};");
}
mLogger.Info($"License verification finished. LicenseKey={licenseKey}; ProductId={productId}; Hostname={hostname};");
return CreateVerificationToken(productId, hostname, licenseKey);
}
private LicenseVerificationToken CreateVerificationToken(string productId, string hostname, string key)
{
X509Certificate2 signingCert = null;
// Try to find the certificate in either the CurrentUser or LocalMachine stores
// to maximize code portability.
signingCert = GetSigningCertificateFrom(StoreLocation.CurrentUser) ?? GetSigningCertificateFrom(StoreLocation.LocalMachine);
if (signingCert == null)
throw new Exception($"No certificate with thumbprint '{mTokenSigningCertificateThumbprint}' was found in the certificate store.");
var info = new LicenseVerificationInfo(productId, hostname, key, DateTime.UtcNow.Ticks);
var token = LicenseVerificationToken.Create(info, signingCert);
return token;
}
private X509Certificate2 GetSigningCertificateFrom(StoreLocation location)
{
var store = new X509Store(StoreName.My, location);
store.Open(OpenFlags.ReadOnly);
try
{
var certificates = store.Certificates.Find(X509FindType.FindByThumbprint, mTokenSigningCertificateThumbprint, validOnly: false);
return certificates.Count > 0 ? certificates[0] : null;
}
finally
{
store.Close();
}
}
private static string CreateBasicAuthenticationToken(string userName, string password)
{
return Convert.ToBase64String(Encoding.UTF8.GetBytes($"{userName}:{password}"), Base64FormattingOptions.None);
}
private static IEnumerable<LicenseInfo> ParseLicenseInfo(string json)
{
var licensesQuery =
from node in JArray.Parse(json)
select new LicenseInfo((string)node["license"]["key"], (int)node["license"]["order_id"]);
return licensesQuery.ToArray();
}
private static OrderInfo ParseOrderInfo(string json)
{
var order = JObject.Parse(json)["order"];
var status = ReadOrderStatus(order);
var isAccessAllowed = (bool) order["access_allowed"];
var subscriptionId = (int?) order["subscription_id"];
var customFields = (JArray)order["order_custom_checkout_fields"];
var hostnames = new List<string>();
if (customFields.Count > 0)
hostnames.Add((string)customFields[0]["order_custom_checkout_field"]["value"]);
if (customFields.Count > 1)
hostnames.Add((string)customFields[1]["order_custom_checkout_field"]["value"]);
return new OrderInfo((int)order["id"], status, isAccessAllowed, subscriptionId, hostnames);
}
private static OrderStatus ReadOrderStatus(JToken order)
{
var dictionary = new Dictionary<string, OrderStatus>
{
{"initial", OrderStatus.Initial },
{"payment_started", OrderStatus.PaymentStarted },
{"payment_pending", OrderStatus.PaymentPending },
{"failed", OrderStatus.Failed },
{"complete", OrderStatus.Complete },
{"chargeback", OrderStatus.Chargeback },
{"refunded", OrderStatus.Refunded },
{"in_dispute", OrderStatus.InDispute },
{"free", OrderStatus.Free },
{"imported", OrderStatus.Imported },
{"fraud_review", OrderStatus.FraudReview },
{"subscription_setup", OrderStatus.SubscriptionSetup },
{"subscription_active", OrderStatus.SubscriptionActive },
{"subscription_complete", OrderStatus.SubscriptionComplete },
{"subscription_cancelled", OrderStatus.SubscriptionCancelled }
};
var status = (string) order["state"];
return dictionary.ContainsKey(status) ? dictionary[status] : OrderStatus.Unknown;
}
}
}

View File

@@ -1,64 +0,0 @@
using System;
using System.IO;
using log4net;
using log4net.Config;
namespace IDeliverable.Licensing.Service.Services
{
public class Logger
{
private const string ConfigFileName = "Log4net.config";
static Logger()
{
var basePath = AppDomain.CurrentDomain.BaseDirectory;
var configFilePath = Path.Combine(basePath, ConfigFileName);
if (File.Exists(configFilePath))
XmlConfigurator.Configure(new FileInfo(configFilePath));
else
throw new Exception($"The log4net configuration file could not be found at path '{configFilePath}'.");
}
public Logger(Type loggerType)
:this(loggerType.FullName)
{
}
public Logger(string loggerName)
{
mLog = LogManager.GetLogger(loggerName);
}
private ILog mLog;
public void Fatal(string message, Exception ex = null)
{
if (mLog.IsFatalEnabled)
mLog.Fatal(message, ex);
}
public void Error(string message, Exception ex = null)
{
if (mLog.IsErrorEnabled)
mLog.Error(message, ex);
}
public void Warn(string message, Exception ex = null)
{
if (mLog.IsWarnEnabled)
mLog.Warn(message, ex);
}
public void Info(string message, Exception ex = null)
{
if (mLog.IsInfoEnabled)
mLog.Info(message, ex);
}
public void Debug(string message, Exception ex = null)
{
if (mLog.IsDebugEnabled)
mLog.Debug(message, ex);
}
}
}

View File

@@ -1,22 +0,0 @@
using System.Collections.Generic;
namespace IDeliverable.Licensing.Service.Services
{
internal class OrderInfo
{
public OrderInfo(int orderId, OrderStatus status, bool isProductAccessAllowed, int? subscriptionId, IEnumerable<string> hostnames)
{
OrderId = orderId;
Hostnames = hostnames;
Status = status;
IsProductAccessAllowed = isProductAccessAllowed;
SubscriptionId = subscriptionId;
}
public int OrderId { get; }
public IEnumerable<string> Hostnames { get; }
public OrderStatus Status { get; }
public bool IsProductAccessAllowed { get; }
public int? SubscriptionId { get; }
}
}

View File

@@ -1,21 +0,0 @@
namespace IDeliverable.Licensing.Service.Services {
internal enum OrderStatus
{
Unknown,
Initial,
PaymentStarted,
PaymentPending,
Failed,
Complete,
Chargeback,
Refunded,
InDispute,
Free,
Imported,
FraudReview,
SubscriptionSetup,
SubscriptionActive,
SubscriptionComplete,
SubscriptionCancelled,
}
}

View File

@@ -1,30 +0,0 @@
<?xml version="1.0"?>
<!-- For more information on using Web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=301874 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your Web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>

View File

@@ -1,31 +0,0 @@
<?xml version="1.0"?>
<!-- For more information on using Web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=301874 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your Web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>

View File

@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="ApiKey" value="MJb17j7YAzSjyEYkhsoI" />
<add key="TestProductId" value="233554" />
<add key="TestHostname" value="ideliverable.com" />
<add key="TestKey" value="ADB5-2D53-0A62-4C2F" />
<add key="SendOwlApiEndpoint" value="https://www.sendowl.com/api/v1/" />
<add key="SendOwlApiKey" value="14be9ee5e05222e" />
<add key="SendOwlApiSecret" value="1a10fe7987724e0a56a1" />
<add key="TokenSigningCertificateThumbprint" value="fa4746a778716109e7e80e1b8dc2ed2a2ba3b852" />
<add key="Logentries.Token" value="5c73ab7f-39a3-4171-b730-03da5c3d4b24"/> <!-- Local -->
<add key="ApplicationInsights.InstrumentationKey" value="" /> <!-- Disabled -->
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Extensibility.Web.RequestTracking.WebRequestTrackingModule, Microsoft.ApplicationInsights.Extensibility.Web" />
</httpModules>
</system.web>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<remove name="ApplicationInsightsWebTracking" />
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Extensibility.Web.RequestTracking.WebRequestTrackingModule, Microsoft.ApplicationInsights.Extensibility.Web" preCondition="managedHandler" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.3" targetFramework="net452" userInstalled="true" />
<package id="logentries.core" version="2.7.0" targetFramework="net452" userInstalled="true" />
<package id="logentries.log4net" version="2.7.0" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights" version="0.14.3-build00177" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.Agent.Intercept" version="0.14.0-build08008" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.JavaScript" version="0.11.0-build09387" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.PerformanceCollector" version="0.14.3-build00177" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.PersistenceChannel" version="0.14.3-build00177" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.RuntimeTelemetry" version="0.14.3-build00177" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.Web" version="0.14.3-build00177" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebApi.HelpPage" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.Bcl" version="1.1.8" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.Diagnostics.Tracing.EventSource.Redist" version="1.1.16-beta" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="3.1.0" targetFramework="net452" userInstalled="true" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" userInstalled="true" />
</packages>

View File

@@ -1,11 +0,0 @@
using System;
using System.Web.Caching;
namespace IDeliverable.Licensing
{
public class CacheInvalidationContext
{
public CacheDependency CacheDependency { get; set; }
public TimeSpan? ValidFor { get; set; }
}
}

View File

@@ -1,52 +0,0 @@
using System;
using System.Web.Caching;
namespace IDeliverable.Licensing
{
public class CacheService
{
private readonly HttpContextAccessor mHttpContextAccessor = new HttpContextAccessor();
private Cache Cache => mHttpContextAccessor.Current().Cache;
public void SetValue<T>(string key, T value, CacheDependency dependency = null, TimeSpan? validFor = null)
{
var absoluteExpiration = validFor != null ? DateTime.UtcNow.Add(validFor.Value) : Cache.NoAbsoluteExpiration;
Cache.Insert(key, value, dependency, absoluteExpiration, Cache.NoSlidingExpiration);
}
public T GetValue<T>(string key, Func<CacheInvalidationContext, T> valueFactory = null)
{
var value = Cache.Get(key);
var exception = value as Exception;
if (exception != null)
throw (Exception)value;
if (value != null)
return (T)value;
if (valueFactory == null)
return default(T);
var context = new CacheInvalidationContext();
try
{
value = valueFactory(context);
SetValue(key, value, context.CacheDependency, context.ValidFor);
return (T) value;
}
catch (Exception ex)
{
SetValue(key, ex, context.CacheDependency, context.ValidFor);
throw;
}
}
public object RemoveValue(string key)
{
return Cache.Remove(key);
}
}
}

View File

@@ -1,11 +0,0 @@
namespace IDeliverable.Licensing.Exceptions
{
public enum LicenseVerificationError
{
UnknownLicenseKey,
NoActiveSubscription,
LicenseRevoked,
HostnameMismatch,
UnhandledException
}
}

View File

@@ -1,29 +0,0 @@
using System;
namespace IDeliverable.Licensing.Exceptions
{
public class LicenseVerificationException : Exception
{
public LicenseVerificationException(LicenseVerificationError error)
:this("An error occurred while verifying the license.", error)
{
}
public LicenseVerificationException(string message, LicenseVerificationError error) : base(message)
{
Error = error;
}
public LicenseVerificationException(LicenseVerificationError error, Exception innerException)
: this("An error occurred while verifying the license.", error, innerException)
{
}
public LicenseVerificationException(string message, LicenseVerificationError error, Exception innerException) : base(message, innerException)
{
Error = error;
}
public LicenseVerificationError Error { get; private set; }
}
}

View File

@@ -1,12 +0,0 @@
using System.Web;
namespace IDeliverable.Licensing
{
public class HttpContextAccessor
{
public HttpContextBase Current()
{
return new HttpContextWrapper(HttpContext.Current);
}
}
}

View File

@@ -1,17 +0,0 @@
using System.Web;
namespace IDeliverable.Licensing
{
internal static class HttpRequestExtensions
{
public static string GetHttpHost(this HttpRequestBase request)
{
var host = request.ServerVariables["HTTP_HOST"];
if (host?.Contains(":") == true)
host = host.Substring(0, host.IndexOf(':'));
return host;
}
}
}

View File

@@ -1,74 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7E439CB7-1ACE-435F-A8F3-5BB929423E34}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IDeliverable.Licensing</RootNamespace>
<AssemblyName>IDeliverable.Licensing</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\lib\newtonsoft.json\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CacheInvalidationContext.cs" />
<Compile Include="CacheService.cs" />
<Compile Include="Exceptions\LicenseVerificationError.cs" />
<Compile Include="Exceptions\LicenseVerificationException.cs" />
<Compile Include="HttpContextAccessor.cs" />
<Compile Include="HttpRequestExtensions.cs" />
<Compile Include="Validation\LicenseValidationError.cs" />
<Compile Include="Validation\LicenseValidationException.cs" />
<Compile Include="Validation\LicenseValidator.cs" />
<Compile Include="VerificationTokens\LicenseVerificationTokenError.cs" />
<Compile Include="VerificationTokens\LicenseVerificationTokenException.cs" />
<Compile Include="VerificationTokens\LicenseVerificationInfo.cs" />
<Compile Include="VerificationTokens\LicenseVerificationToken.cs" />
<Compile Include="VerificationTokens\LicenseVerificationTokenAccessor.cs" />
<Compile Include="VerificationTokens\LicensingServiceClient.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Validation\LicenseValidationOptions.cs" />
<Compile Include="VerificationTokens\ILicenseVerificationTokenStore.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IDeliverable.LicensingFramework")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IDeliverable.LicensingFramework")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7e439cb7-1ace-435f-a8f3-5bb929423e34")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,15 +0,0 @@
namespace IDeliverable.Licensing.Validation
{
public enum LicenseValidationError
{
UnknownLicenseKey,
HostnameMismatch,
NoActiveSubscription,
LicenseRevoked,
LicensingServiceError,
LicensingServiceUnreachable,
TokenAgeValidationFailed,
TokenSignatureValidationFailed,
UnexpectedError,
}
}

View File

@@ -1,29 +0,0 @@
using System;
namespace IDeliverable.Licensing.Validation
{
public class LicenseValidationException : Exception
{
public LicenseValidationException(LicenseValidationError error)
:this("An error occurred while validating the license.", error)
{
}
public LicenseValidationException(string message, LicenseValidationError error) : base(message)
{
Error = error;
}
public LicenseValidationException(LicenseValidationError error, Exception innerException)
: this("An error occurred while validating the license.", error, innerException)
{
}
public LicenseValidationException(string message, LicenseValidationError error, Exception innerException) : base(message, innerException)
{
Error = error;
}
public LicenseValidationError Error { get; private set; }
}
}

View File

@@ -1,12 +0,0 @@
using System;
namespace IDeliverable.Licensing.Validation
{
[Flags]
public enum LicenseValidationOptions
{
Default = 0,
SkipForLocalRequests = 1,
ForceRenewToken = 2,
}
}

View File

@@ -1,141 +0,0 @@
using System;
using System.Security.Cryptography.X509Certificates;
using IDeliverable.Licensing.VerificationTokens;
namespace IDeliverable.Licensing.Validation
{
public class LicenseValidator
{
private static readonly TimeSpan sVerificationTokenValidFor = TimeSpan.FromDays(21);
private static readonly TimeSpan sAllowableClockSkew = TimeSpan.FromMinutes(10);
public LicenseValidator(LicenseVerificationTokenAccessor verificationTokenAccessor)
{
mHttpContextAccessor = new HttpContextAccessor();
mVerificationTokenAccessor = verificationTokenAccessor;
}
private readonly HttpContextAccessor mHttpContextAccessor;
private readonly LicenseVerificationTokenAccessor mVerificationTokenAccessor;
public void ValidateLicense(string productId, string licenseKey, LicenseValidationOptions options = LicenseValidationOptions.Default)
{
var request = mHttpContextAccessor.Current().Request;
var skipForLocalRequests = (options & LicenseValidationOptions.SkipForLocalRequests) == LicenseValidationOptions.SkipForLocalRequests;
if (request.IsLocal && skipForLocalRequests)
return;
LicenseVerificationToken token;
try
{
var forceRenewToken = (options & LicenseValidationOptions.ForceRenewToken) == LicenseValidationOptions.ForceRenewToken;
token = mVerificationTokenAccessor.GetLicenseVerificationToken(productId, licenseKey, request.GetHttpHost(), forceRenewToken);
// If the token we got back is too old to be considered valid anymore, try to get the token
// again, this time forcing token renewal.
if (token.Age > sVerificationTokenValidFor)
token = mVerificationTokenAccessor.GetLicenseVerificationToken(productId, licenseKey, request.GetHttpHost(), forceRenew: true);
}
catch (LicenseVerificationTokenException ex)
{
var error = LicenseValidationError.UnexpectedError;
switch (ex.Error)
{
case LicenseVerificationTokenError.UnknownLicenseKey:
error = LicenseValidationError.UnknownLicenseKey;
break;
case LicenseVerificationTokenError.HostnameMismatch:
error = LicenseValidationError.HostnameMismatch;
break;
case LicenseVerificationTokenError.NoActiveSubscription:
error = LicenseValidationError.NoActiveSubscription;
break;
case LicenseVerificationTokenError.LicenseRevoked:
error = LicenseValidationError.LicenseRevoked;
break;
case LicenseVerificationTokenError.LicenseServiceError:
error = LicenseValidationError.LicensingServiceError;
break;
case LicenseVerificationTokenError.LicenseServiceUnreachable:
error = LicenseValidationError.LicensingServiceUnreachable;
break;
}
throw new LicenseValidationException(ex.Message, error);
}
catch (Exception ex)
{
throw new LicenseValidationException("An unexpected error occurred while validating the license.", LicenseValidationError.UnexpectedError, ex);
}
// It should never happen that at this point we don't have a token or it's too old.
if (token == null || token.Age > sVerificationTokenValidFor)
throw new LicenseValidationException(LicenseValidationError.UnexpectedError);
// If the token age is negative by more than 10 minutes (allowable clock skew between licensing
// service and local machine) then this is a strong indication of an attempt to bypass license
// validation by changing the system clock.
if (token.Age < -sAllowableClockSkew)
throw new LicenseValidationException("The license verification token age is negative by more than the allowable clock skew. This might indicate that system clock of either the client or the licensing service is offset.", LicenseValidationError.TokenAgeValidationFailed);
var signingCertificate = GetSigningCertificate();
if (!token.GetSignatureIsValid(signingCertificate))
throw new LicenseValidationException("License verification token signature validation failed.", LicenseValidationError.TokenSignatureValidationFailed);
}
private static X509Certificate2 GetSigningCertificate()
{
const string certBase64 =
@"MIIG0TCCBLmgAwIBAgIQ7qnUeLGos7hDPcw3o9G74jANBgkqhkiG9w0BAQ0FADCB
ozELMAkGA1UEBhMCQ1kxETAPBgNVBAgTCExpbWFzc29sMREwDwYDVQQHEwhMaW1h
c3NvbDEZMBcGA1UEChMQSURlbGl2ZXJhYmxlIEx0ZDETMBEGA1UECxMKT3BlcmF0
aW9uczEYMBYGA1UEAxMPSURlbGl2ZXJhYmxlIENBMSQwIgYJKoZIhvcNAQkBFhVp
bmZvQGlkZWxpdmVyYWJsZS5jb20wHhcNMTQxMjMxMjEwMDAwWhcNMjQxMjMxMjEw
MDAwWjCBrjELMAkGA1UEBhMCQ1kxETAPBgNVBAgTCExpbWFzc29sMREwDwYDVQQH
EwhMaW1hc3NvbDEZMBcGA1UEChMQSURlbGl2ZXJhYmxlIEx0ZDETMBEGA1UECxMK
T3BlcmF0aW9uczEjMCEGA1UEAxMabGljZW5zaW5nLmlkZWxpdmVyYWJsZS5jb20x
JDAiBgkqhkiG9w0BCQEWFWluZm9AaWRlbGl2ZXJhYmxlLmNvbTCCAiIwDQYJKoZI
hvcNAQEBBQADggIPADCCAgoCggIBAJ0LddkeiE9f0p60exUCR1PxrKBHoVwF5von
Lq+4GxA4I7Frtt8MV/dEYnYT44d/S6lEkAPLfF70CnyyWfpPO7MkIJYlFNZ2eJSz
9wu0VZ12CZO9RilxrEzK1xLS+f6g7P+rPP3m1CqSt84wpd3YloLdBuB3HwPWNh5H
a0Ew7W6IKyhzIX4MNzXXNc2evDIoaur3jQiPewtSastXzSQEEUx+S4St4qFbJ8lK
v6pwC1BmqX37uoNURqqS1CWg3iKiAfzqtTIwt9vBu8C1ev4ZnlKmAF4C1fTuH3Wo
X1lT+wpkycqWIUxoV7zoXYpxkleeNCw/GavDYmqhfU0qSjI4bdD/uy0s66dubtWB
rCZ3VRC7mjHhmEWj1Y9GYvvg6Fjt/BchVMNEhIBd873MdXDqIx0cV6SILiQgudtr
uvAUm5rT6KEYNSsHq9gQWN+LAgy8mDSOGLjYXdBtAOJMxS/w8XNA+bXWzvNYOl9q
QO8w7Py3U/8mnLkxgHaVGktWazwQ1QkwaLyQz7lbTBedXkxOzP3LvLAe+POd4Zre
wYcNUs/W51WfLup9o/IMEvDk/z0FCJ1fGFiHny3QFWrhJB3dAia1dwYtUpy42ZuY
w4UQEuZVr3BzDCXudx6638WOURpvaMe/Enfdr2bcqvCYvzbT06RPD/VTtuKtZ8O7
Q/hr0NvTAgMBAAGjgfMwgfAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwgdgGA1UdAQSB
0DCBzYAQFBF2JL0Y1AduVxGNb4H7DqGBpjCBozELMAkGA1UEBhMCQ1kxETAPBgNV
BAgTCExpbWFzc29sMREwDwYDVQQHEwhMaW1hc3NvbDEZMBcGA1UEChMQSURlbGl2
ZXJhYmxlIEx0ZDETMBEGA1UECxMKT3BlcmF0aW9uczEYMBYGA1UEAxMPSURlbGl2
ZXJhYmxlIENBMSQwIgYJKoZIhvcNAQkBFhVpbmZvQGlkZWxpdmVyYWJsZS5jb22C
EMgq1WuLQwSJTj+ogMza3/YwDQYJKoZIhvcNAQENBQADggIBAEU9gdrydWT3ZwtA
LP/HEct2DJRQdK9WuL02x2xbdmszyb8xoayTIcJdvs2WHPBqxM417XAhNTZuG3Aw
Yx6OPSzbfmS1X7aVctSeBwZCfzxOk2MhTsKoZ+wjmFn6LVYz3P6K2deJVz6t+HRc
mMwFrsctzgGZsxIvMXa0eqyDE6hhxj0XKYLFmYNGBdUd5sW68Ko26Njv1FPLkoqo
Me2y+Gi6SltgjD/bmza36IRvaQVQtOjOxq+TncOBqLJ2+ikQOr93pkCgx3nso3CM
YH1ryRpXbSAb5aA9sF0jb6LLLUgHv5q2ExpEFcoRja5gww5R2VKwEJ2PXjK+2O/A
DgHOLKuiODxBF61+Ou/d29XiSX2HxCoH+onppi2h6ceJPcFwPrgzKVszsGkavtKL
7myxufgdBUgTFxYMaTEtrU0yaRiJItxreH1wj/vl1zKyl25MXZLM1LyFvszAX49h
9hgWApwE9hL1i6ygIfrpq2B+djPS8ZwX5S/t/QO5SmBjNLmw1GD1gHN5xqY0vMzS
VxDXrH6Kllhwipu8GLeMWn/VmWWLy1vr//GoBjujhplIZHJPYBrYjqwfxH1ZLa4B
O+N7bHDp63M0UVX5FdX1sN0laL29L1jXX/oe7x8PHNt3W4aOwVaIilh+/adXNDxr
1yumH4G7QEeMQisiMhlPxnZJHajX";
var certBytes = Convert.FromBase64String(certBase64);
var cert = new X509Certificate2(certBytes);
return cert;
}
}
}

View File

@@ -1,9 +0,0 @@
namespace IDeliverable.Licensing.VerificationTokens
{
public interface ILicenseVerificationTokenStore
{
LicenseVerificationToken Load(string productId);
void Save(string productId, LicenseVerificationToken token);
void Clear(string productId);
}
}

View File

@@ -1,36 +0,0 @@
using System;
using Newtonsoft.Json;
namespace IDeliverable.Licensing.VerificationTokens
{
public class LicenseVerificationInfo
{
public LicenseVerificationInfo(string productId, string hostname, string licenseKey, long verifiedUtcTicks)
{
ProductId = productId;
Hostname = hostname;
LicenseKey = licenseKey;
VerifiedUtcTicks = verifiedUtcTicks;
}
public string ProductId { get; }
public string Hostname { get; }
public string LicenseKey { get; }
public long VerifiedUtcTicks { get; }
public DateTime VerifiedUtc => new DateTime(VerifiedUtcTicks, DateTimeKind.Utc);
public TimeSpan Age => DateTime.UtcNow - VerifiedUtc;
public override string ToString()
{
return JsonConvert.SerializeObject(
new
{
ProductId,
Hostname,
LicenseKey,
VerifiedUtcTicks
});
}
}
}

View File

@@ -1,72 +0,0 @@
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace IDeliverable.Licensing.VerificationTokens
{
public class LicenseVerificationToken
{
public static LicenseVerificationToken Create(LicenseVerificationInfo info, X509Certificate2 signingCert)
{
var infoString = info.ToString();
var infoBytes = Encoding.UTF8.GetBytes(infoString);
var privateKey = (RSACryptoServiceProvider)signingCert.PrivateKey;
var signatureBytes = privateKey.SignData(infoBytes, "md5");
var signature = Convert.ToBase64String(signatureBytes);
return new LicenseVerificationToken(info, signature);
}
public static LicenseVerificationToken FromBase64(string value)
{
var tokenBytes = Convert.FromBase64String(value);
var tokenJson = Encoding.UTF8.GetString(tokenBytes);
return Parse(tokenJson);
}
public static LicenseVerificationToken Parse(string value)
{
return JsonConvert.DeserializeObject<LicenseVerificationToken>(value, new StringEnumConverter());
}
public LicenseVerificationToken(LicenseVerificationInfo info, string signature)
{
if (info == null)
throw new ArgumentNullException(nameof(info), $"The parameter {nameof(info)} cannot be null.");
Info = info;
Signature = signature;
}
public LicenseVerificationInfo Info { get; }
public string Signature { get; }
public DateTime VerifiedUtc => Info.VerifiedUtc; // Delegated to Info because it needs to be included in signature.
public TimeSpan Age => Info.Age; // Delegated to Info because it needs to be included in signature.
public string ToBase64()
{
var tokenJson = ToString();
var tokenBytes = Encoding.UTF8.GetBytes(tokenJson);
return Convert.ToBase64String(tokenBytes);
}
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
public bool GetSignatureIsValid(X509Certificate2 signingCert)
{
var publicKey = (RSACryptoServiceProvider)signingCert.PublicKey.Key;
var infoBytes = Encoding.UTF8.GetBytes(Info.ToString());
var signatureBytes = Convert.FromBase64String(Signature);
var isValid = publicKey.VerifyData(infoBytes, "md5", signatureBytes);
return isValid;
}
}
}

View File

@@ -1,73 +0,0 @@
using System;
namespace IDeliverable.Licensing.VerificationTokens
{
public class LicenseVerificationTokenAccessor
{
private static readonly TimeSpan sTokenRenewalInterval = TimeSpan.FromHours(48);
public LicenseVerificationTokenAccessor(ILicenseVerificationTokenStore store)
{
mStore = store;
mLicensingServiceClient = new LicensingServiceClient();
}
private readonly ILicenseVerificationTokenStore mStore;
private readonly LicensingServiceClient mLicensingServiceClient;
public LicenseVerificationToken GetLicenseVerificationToken(string productId, string licenseKey, string hostname, bool forceRenew = false)
{
var token = mStore.Load(productId);
// Delete the existing verification token from store if:
// * It was issued for a different license key OR
// * We are instructed by caller to force renewal
if (token != null && (token.Info.LicenseKey != licenseKey || forceRenew))
{
mStore.Clear(productId);
token = null;
}
// Try to renew verification token from licensing service if:
// * We don't have a token in store OR
// * The one we have has passed the token renewal interval
if (token == null || token.Age > sTokenRenewalInterval)
{
try
{
token = mLicensingServiceClient.VerifyLicense(productId, licenseKey, hostname);
}
catch (Exception ex)
{
// If the license key is reported by licensing service to be either invalid or for
// a different hostname, we delete any existing token from store and throw unconditionally.
if (ex is LicenseVerificationTokenException)
{
var lvtex = (LicenseVerificationTokenException)ex;
if (lvtex.Error == LicenseVerificationTokenError.UnknownLicenseKey ||
lvtex.Error == LicenseVerificationTokenError.HostnameMismatch ||
lvtex.Error == LicenseVerificationTokenError.NoActiveSubscription ||
lvtex.Error == LicenseVerificationTokenError.LicenseRevoked)
{
mStore.Clear(productId);
throw;
}
}
// If we have an existing token from before, return it rather than throwing.
if (token != null)
return token;
if (ex is LicenseVerificationTokenException)
throw;
throw new LicenseVerificationTokenException(LicenseVerificationTokenError.UnexpectedError, ex);
}
mStore.Save(productId, token);
}
return token;
}
}
}

View File

@@ -1,13 +0,0 @@
namespace IDeliverable.Licensing.VerificationTokens
{
public enum LicenseVerificationTokenError
{
UnknownLicenseKey,
HostnameMismatch,
NoActiveSubscription,
LicenseRevoked,
LicenseServiceError,
LicenseServiceUnreachable,
UnexpectedError
}
}

View File

@@ -1,29 +0,0 @@
using System;
namespace IDeliverable.Licensing.VerificationTokens
{
public class LicenseVerificationTokenException : Exception
{
public LicenseVerificationTokenException(LicenseVerificationTokenError error)
:this("An error occurred while getting a license verification token.", error)
{
}
public LicenseVerificationTokenException(string message, LicenseVerificationTokenError error) : base(message)
{
Error = error;
}
public LicenseVerificationTokenException(LicenseVerificationTokenError error, Exception innerException)
: this("An error occurred while getting a license verification token.", error, innerException)
{
}
public LicenseVerificationTokenException(string message, LicenseVerificationTokenError error, Exception innerException) : base(message, innerException)
{
Error = error;
}
public LicenseVerificationTokenError Error { get; private set; }
}
}

View File

@@ -1,97 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using IDeliverable.Licensing.Exceptions;
namespace IDeliverable.Licensing.VerificationTokens
{
public class LicensingServiceClient
{
// These are consciously hard coded (need to be obfuscated).
private static readonly string sLicensingServiceUrl = "https://licensing.ideliverable.com/api/v1/";
private static readonly string sLicensingServiceApiKey = "MJb17j7YAzSjyEYkhsoI";
private static readonly string sExpectedServerCertificateThumbprint = "fa4746a778716109e7e80e1b8dc2ed2a2ba3b852";
public LicenseVerificationToken VerifyLicense(string productId, string licenseKey, string hostname)
{
RemoteCertificateValidationCallback certValidationHandler = (sender, certificate, chain, errors) =>
{
// Accept the server certificate as long as it matches the expected thumbprint. This makes sure
// that the API call works even if the client host doesn't trust IDeliverable CA certificate, but
// fails if somebody is trying to spoof the service.
var serverCertThumbprint = ((X509Certificate2)certificate).Thumbprint;
return String.Equals(serverCertThumbprint, sExpectedServerCertificateThumbprint, StringComparison.OrdinalIgnoreCase);
};
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(sLicensingServiceUrl);
client.DefaultRequestHeaders.Add("ApiKey", sLicensingServiceApiKey);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
ServicePointManager.ServerCertificateValidationCallback += certValidationHandler;
try
{
HttpResponseMessage response;
try
{
response = client.GetAsync($"license/{licenseKey}/verify?productId={productId}&hostname={hostname}").Result;
}
catch (Exception ex)
{
throw new LicenseVerificationTokenException("An error occurred while calling the licensing service.", LicenseVerificationTokenError.LicenseServiceUnreachable, ex);
}
if (!response.IsSuccessStatusCode)
{
var licenseVerificationError = ReadLicenseVerificationError(response);
switch (licenseVerificationError)
{
case LicenseVerificationError.UnknownLicenseKey:
throw new LicenseVerificationTokenException(response.ReasonPhrase, LicenseVerificationTokenError.UnknownLicenseKey);
case LicenseVerificationError.HostnameMismatch:
throw new LicenseVerificationTokenException(response.ReasonPhrase, LicenseVerificationTokenError.HostnameMismatch);
case LicenseVerificationError.NoActiveSubscription:
throw new LicenseVerificationTokenException(response.ReasonPhrase, LicenseVerificationTokenError.NoActiveSubscription);
case LicenseVerificationError.LicenseRevoked:
throw new LicenseVerificationTokenException(response.ReasonPhrase, LicenseVerificationTokenError.LicenseRevoked);
default:
throw new LicenseVerificationTokenException(response.ReasonPhrase, LicenseVerificationTokenError.LicenseServiceError);
}
}
var responseText = response.Content.ReadAsStringAsync().Result;
var token = LicenseVerificationToken.Parse(responseText);
return token;
}
finally
{
ServicePointManager.ServerCertificateValidationCallback -= certValidationHandler;
}
}
}
private static LicenseVerificationError? ReadLicenseVerificationError(HttpResponseMessage response)
{
IEnumerable<string> values;
if (!response.Headers.TryGetValues("LicensingErrorCode", out values))
return null;
var value = values.First();
return (LicenseVerificationError)Enum.Parse(typeof(LicenseVerificationError), value);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +0,0 @@
<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Practices.ServiceLocation" publicKeyToken="31BF3856AD364E35"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.0.0" newVersion="1.2.0.0" />
</dependentAssembly>
</assemblyBinding>
<loadFromRemoteSources enabled="true" />
</runtime>
</configuration>

View File

@@ -18,7 +18,7 @@
</appSettings>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<pages pageBaseType="Orchard.Mvc.ViewEngines.Razor.WebViewPage">
<namespaces>
<add namespace="System.Collections.Generic"/>
@@ -60,7 +60,7 @@
<add extension=".csproj" type="Orchard.Environment.Extensions.Compilers.CSharpExtensionBuildProviderShim"/>
</buildProviders>
<assemblies>
<add assembly="System.Web.Mvc, Version=5..0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
@@ -147,7 +147,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
@@ -171,11 +171,11 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral"/>

View File

@@ -20,6 +20,7 @@ using Orchard.DisplayManagement.Implementation;
using Orchard.Environment;
using Orchard.Environment.Extensions;
using Orchard.Security;
using Orchard.Tests.ContentManagement;
using Orchard.Tests.Modules;
using Orchard.Tests.Stubs;
using Orchard.UI.Notify;
@@ -35,7 +36,6 @@ namespace Orchard.Core.Tests.Body {
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);
builder.RegisterInstance(new Mock<ITransactionManager>().Object);
builder.RegisterInstance(new Mock<IAuthorizer>().Object);
builder.RegisterInstance(new Mock<INotifier>().Object);
builder.RegisterInstance(new Mock<IContentDisplay>().Object);

View File

@@ -85,6 +85,7 @@
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\..\lib\sqlce\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>

View File

@@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.9.0")]
[assembly: AssemblyFileVersion("1.9.0")]
[assembly: AssemblyVersion("1.9.1")]
[assembly: AssemblyFileVersion("1.9.1")]

View File

@@ -35,7 +35,6 @@ namespace Orchard.Core.Tests.Scheduling {
public override void Register(ContainerBuilder builder) {
_handler = new StubTaskHandler();
builder.RegisterInstance(new Mock<IOrchardServices>().Object);
builder.RegisterInstance(new Mock<ITransactionManager>().Object);
builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();

View File

@@ -13,6 +13,7 @@ using Orchard.Core.Settings.Metadata;
using Orchard.Core.Settings.Metadata.Records;
using Orchard.Data;
using Orchard.Tests;
using Orchard.Tests.ContentManagement;
using Orchard.Tests.Stubs;
using Orchard.Tests.Utility;
@@ -23,6 +24,7 @@ namespace Orchard.Core.Tests.Settings.Metadata {
private ISessionFactory _sessionFactory;
private ISession _session;
private IContainer _container;
private ITransactionManager _transactionManager;
[TestFixtureSetUp]
public void InitFixture() {
@@ -39,6 +41,17 @@ namespace Orchard.Core.Tests.Settings.Metadata {
[SetUp]
public void Init() {
_session = _sessionFactory.OpenSession();
foreach (var killType in new[] { typeof(ContentTypeDefinitionRecord), typeof(ContentPartDefinitionRecord), typeof(ContentFieldDefinitionRecord) }) {
foreach (var killRecord in _session.CreateCriteria(killType).List()) {
_session.Delete(killRecord);
}
}
_session.Flush();
_session.Close();
_session.Dispose();
_session = _sessionFactory.OpenSession();
var builder = new ContainerBuilder();
builder.RegisterAutoMocking();
builder.RegisterType<ContentDefinitionManager>().As<IContentDefinitionManager>();
@@ -48,25 +61,15 @@ namespace Orchard.Core.Tests.Settings.Metadata {
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<StubParallelCacheContext>().As<IParallelCacheContext>();
_session = _sessionFactory.OpenSession();
builder.RegisterInstance(_transactionManager = new TestTransactionManager(_session)).As<ITransactionManager>();
_container = builder.Build();
_container.Mock<ISessionLocator>()
.Setup(x => x.For(It.IsAny<Type>()))
.Returns(() => _session);
_session = _sessionFactory.OpenSession();
foreach (var killType in new[] { typeof(ContentTypeDefinitionRecord), typeof(ContentPartDefinitionRecord), typeof(ContentFieldDefinitionRecord) }) {
foreach (var killRecord in _session.CreateCriteria(killType).List()) {
_session.Delete(killRecord);
}
}
_session.Flush();
}
void ResetSession() {
_session.Flush();
_session.Dispose();
_session = _sessionFactory.OpenSession();
_transactionManager.RequireNew();
}
[TearDown]

View File

@@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.9.0")]
[assembly: AssemblyFileVersion("1.9.0")]
[assembly: AssemblyVersion("1.9.1")]
[assembly: AssemblyFileVersion("1.9.1")]

View File

@@ -93,13 +93,14 @@ namespace Orchard.Specs.Bindings {
_webHost = new WebHost(_orchardTemp);
Host.Initialize(siteFolder, virtualDirectory ?? "/", _dynamicCompilationOption);
var shuttle = new Shuttle();
Host.Execute(() => {
log4net.Config.BasicConfigurator.Configure(new CastleAppender());
HostingTraceListener.SetHook(msg => shuttle._sink.Receive(msg));
});
Host.Execute(() => Executor(shuttle));
_messages = shuttle._sink;
}
private static void Executor(Shuttle shuttle) {
HostingTraceListener.SetHook(msg => shuttle._sink.Receive(msg));
}
private class CastleAppender : IAppender {
public void Close() { }
public string Name { get; set; }

View File

@@ -7,7 +7,7 @@
<system.web>
<compilation targetFramework="4.5">
<assemblies>
<add assembly="System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
</assemblies>
</compilation>
<pages>

View File

@@ -10,11 +10,11 @@
-->
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<controls>
<add assembly="System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" namespace="System.Web.Mvc" tagPrefix="mvc" />
<add assembly="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
</system.web>

View File

@@ -21,13 +21,13 @@
<appSettings>
<add key="webpages:Enabled" value="false" />
<add key="webpages:Version" value="3.0.0.0"/>
<add key="webpages:Version" value="3.0.0"/>
<add key="log4net.Config" value="Config\log4net.config" />
<add key="owin:AutomaticAppStartup" value="false" />
</appSettings>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<pages pageBaseType="Orchard.Mvc.ViewEngines.Razor.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
@@ -62,7 +62,7 @@
<add extension=".csproj" type="Orchard.Environment.Extensions.Compilers.CSharpExtensionBuildProviderShim"/>
</buildProviders>
<assemblies>
<add assembly="System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
@@ -150,63 +150,74 @@
<httpErrors existingResponse="PassThrough" />
</system.webServer>
<runtime>
<gcServer enabled="true"/>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="App_Data/Dependencies"/>
<dependentAssembly>
<assemblyIdentity name="Iesi.Collections" publicKeyToken="AA95F207798DFDB4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Deployment" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.WebPages.Deployment" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.0.4000" newVersion="4.0.0.4000"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da"/>
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed"/>
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.WindowsAzure.Storage" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.6.3.0" newVersion="5.6.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.6.3.0" newVersion="5.6.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.6.3.0" newVersion="5.6.3.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Some files were not shown because too many files have changed in this diff Show More