diff --git a/ClickToRunAzureInDevFabric.cmd b/ClickToRunAzureInDevFabric.cmd new file mode 100644 index 000000000..3e1ba1773 --- /dev/null +++ b/ClickToRunAzureInDevFabric.cmd @@ -0,0 +1,5 @@ +SET CDIR = %CD% +call "%ProgramFiles%\Windows Azure SDK\v1.3\bin\setenv.cmd" +csrun /devstore +csrun /run:"%CDIR %\build\Compile\Orchard.Azure.CloudService.csx";"%CDIR %\src\Orchard.Azure\Orchard.Azure.CloudService\ServiceConfiguration.cscfg" /launchbrowser +pause \ No newline at end of file diff --git a/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs b/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs index 5c5e33d98..524c02777 100644 --- a/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs +++ b/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs @@ -83,32 +83,27 @@ namespace Orchard.Azure.Environment.Configuration { } } - class Content { - public string Name { get; set; } - public string DataProvider { get; set; } - public string DataConnectionString { get; set; } - public string DataPrefix { get; set; } - public string RequestUrlHost { get; set; } - public string RequestUrlPrefix { get; set; } - public string State { get; set; } - } - - static ShellSettings ParseSettings(string text) { + static ShellSettings ParseSettings(string text) + { var shellSettings = new ShellSettings(); - if ( String.IsNullOrEmpty(text) ) + if (String.IsNullOrEmpty(text)) return shellSettings; string[] settings = text.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); - foreach ( var setting in settings ) { + foreach (var setting in settings) + { string[] settingFields = setting.Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries); int fieldsLength = settingFields.Length; - if ( fieldsLength != 2 ) + if (fieldsLength != 2) continue; - for ( int i = 0; i < fieldsLength; i++ ) { + for (int i = 0; i < fieldsLength; i++) + { settingFields[i] = settingFields[i].Trim(); } - if ( settingFields[1] != "null" ) { - switch ( settingFields[0] ) { + if (settingFields[1] != "null") + { + switch (settingFields[0]) + { case "Name": shellSettings.Name = settingFields[1]; break; @@ -130,24 +125,38 @@ namespace Orchard.Azure.Environment.Configuration { case "RequestUrlPrefix": shellSettings.RequestUrlPrefix = settingFields[1]; break; + case "EncryptionAlgorithm": + shellSettings.EncryptionAlgorithm = settingFields[1]; + break; + case "EncryptionKey": + shellSettings.EncryptionKey = settingFields[1]; + break; + case "EncryptionIV": + shellSettings.EncryptionIV = settingFields[1]; + break; } } } return shellSettings; } - static string ComposeSettings(ShellSettings settings) { - if ( settings == null ) + static string ComposeSettings(ShellSettings settings) + { + if (settings == null) return ""; - return string.Format("Name: {0}\r\nDataProvider: {1}\r\nDataConnectionString: {2}\r\nDataPrefix: {3}\r\nRequestUrlHost: {4}\r\nRequestUrlPrefix: {5}\r\nState: {6}\r\n", + return string.Format("Name: {0}\r\nDataProvider: {1}\r\nDataConnectionString: {2}\r\nDataPrefix: {3}\r\nRequestUrlHost: {4}\r\nRequestUrlPrefix: {5}\r\nState: {6}\r\nEncryptionAlgorithm: {7}\r\nEncryptionKey: {8}\r\nEncryptionIV: {9}\r\n", settings.Name, settings.DataProvider, settings.DataConnectionString ?? "null", settings.DataTablePrefix ?? "null", settings.RequestUrlHost ?? "null", settings.RequestUrlPrefix ?? "null", - settings.State != null ? settings.State.ToString() : String.Empty); + settings.State != null ? settings.State.ToString() : String.Empty, + settings.EncryptionAlgorithm ?? "null", + settings.EncryptionKey ?? "null", + settings.EncryptionIV ?? "null" + ); } } } diff --git a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef index fb41cf303..462e8f2ae 100644 --- a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef +++ b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef @@ -1,13 +1,6 @@  - - - - - - - diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj index 981db132f..4db91e723 100644 --- a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj +++ b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj @@ -75,8 +75,9 @@ False - - True + + False + ..\..\..\lib\sqlce\System.Data.SqlServerCe.dll False diff --git a/src/Orchard.Tests/Stubs/StubWorkContextAccessor.cs b/src/Orchard.Tests/Stubs/StubWorkContextAccessor.cs index ee299df51..80fde47de 100644 --- a/src/Orchard.Tests/Stubs/StubWorkContextAccessor.cs +++ b/src/Orchard.Tests/Stubs/StubWorkContextAccessor.cs @@ -60,6 +60,11 @@ namespace Orchard.Tests.Stubs { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } + + public int PageSize { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } } public class StubUser : IUser { diff --git a/src/Orchard.Web/Core/Containers/Controllers/ItemController.cs b/src/Orchard.Web/Core/Containers/Controllers/ItemController.cs index db89f21be..6bb1e3618 100644 --- a/src/Orchard.Web/Core/Containers/Controllers/ItemController.cs +++ b/src/Orchard.Web/Core/Containers/Controllers/ItemController.cs @@ -11,20 +11,29 @@ using Orchard.Themes; using Orchard.UI.Navigation; namespace Orchard.Core.Containers.Controllers { + using Orchard.Settings; + public class ItemController : Controller { private readonly IContentManager _contentManager; private readonly IContainersPathConstraint _containersPathConstraint; + private readonly ISiteService _siteService; + + public ItemController( + IContentManager contentManager, + IContainersPathConstraint containersPathConstraint, + IShapeFactory shapeFactory, + ISiteService siteService) { - public ItemController(IContentManager contentManager, IContainersPathConstraint containersPathConstraint, IShapeFactory shapeFactory) { _contentManager = contentManager; _containersPathConstraint = containersPathConstraint; + _siteService = siteService; Shape = shapeFactory; } dynamic Shape { get; set; } [Themed] - public ActionResult Display(string path, Pager pager) { + public ActionResult Display(string path, PagerParameters pagerParameters) { var matchedPath = _containersPathConstraint.FindPath(path); if (string.IsNullOrEmpty(matchedPath)) { throw new ApplicationException("404 - should not have passed path constraint"); @@ -51,7 +60,8 @@ namespace Orchard.Core.Containers.Controllers { var descendingOrder = container.As().Record.OrderByDirection == (int) OrderByDirection.Descending; query = query.OrderBy(container.As().Record.OrderByProperty, descendingOrder); - pager.PageSize = pager.PageSize != Pager.PageSizeDefault && container.As().Record.Paginated + Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters); + pager.PageSize = pagerParameters.PageSize != null && container.As().Record.Paginated ? pager.PageSize : container.As().Record.PageSize; var pagerShape = Shape.Pager(pager).TotalItemCount(query.Count()); diff --git a/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs b/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs index c638153f0..f8a16d634 100644 --- a/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs +++ b/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs @@ -17,6 +17,7 @@ using Orchard.Localization; using Orchard.Logging; using Orchard.UI.Navigation; using Orchard.UI.Notify; +using Orchard.Settings; namespace Orchard.Core.Contents.Controllers { [ValidateInput(false)] @@ -24,17 +25,20 @@ namespace Orchard.Core.Contents.Controllers { private readonly IContentManager _contentManager; private readonly IContentDefinitionManager _contentDefinitionManager; private readonly ITransactionManager _transactionManager; + private readonly ISiteService _siteService; public AdminController( IOrchardServices orchardServices, IContentManager contentManager, IContentDefinitionManager contentDefinitionManager, ITransactionManager transactionManager, + ISiteService siteService, IShapeFactory shapeFactory) { Services = orchardServices; _contentManager = contentManager; _contentDefinitionManager = contentDefinitionManager; _transactionManager = transactionManager; + _siteService = siteService; T = NullLocalizer.Instance; Logger = NullLogger.Instance; Shape = shapeFactory; @@ -45,7 +49,8 @@ namespace Orchard.Core.Contents.Controllers { public Localizer T { get; set; } public ILogger Logger { get; set; } - public ActionResult List(ListContentsViewModel model, Pager pager) { + public ActionResult List(ListContentsViewModel model, PagerParameters pagerParameters) { + Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters); if (model.ContainerId != null && _contentManager.GetLatest((int)model.ContainerId) == null) return HttpNotFound(); diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj index c06905952..0c9308d99 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -104,6 +104,7 @@ + diff --git a/src/Orchard.Web/Core/Routable/Events/ISlugEventHandler.cs b/src/Orchard.Web/Core/Routable/Events/ISlugEventHandler.cs new file mode 100644 index 000000000..a178aed71 --- /dev/null +++ b/src/Orchard.Web/Core/Routable/Events/ISlugEventHandler.cs @@ -0,0 +1,17 @@ +using Orchard.Events; + +namespace Orchard.Core.Routable.Events { + public interface ISlugEventHandler : IEventHandler { + void FillingSlugFromTitle(FillSlugContext context); + void FilledSlugFromTitle(FillSlugContext context); + } + + public class FillSlugContext { + public FillSlugContext(string slug) { + Slug = slug; + } + + public string Slug { get; set; } + public bool Adjusted { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Routable/Services/RoutableService.cs b/src/Orchard.Web/Core/Routable/Services/RoutableService.cs index 2ddea2f21..889720db9 100644 --- a/src/Orchard.Web/Core/Routable/Services/RoutableService.cs +++ b/src/Orchard.Web/Core/Routable/Services/RoutableService.cs @@ -1,18 +1,23 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; +using System.Text; using System.Text.RegularExpressions; using Orchard.ContentManagement; using Orchard.ContentManagement.Aspects; using Orchard.Core.Common.Models; +using Orchard.Core.Routable.Events; using Orchard.Core.Routable.Models; namespace Orchard.Core.Routable.Services { public class RoutableService : IRoutableService { private readonly IContentManager _contentManager; + private readonly IEnumerable _slugEventHandlers; - public RoutableService(IContentManager contentManager) { + public RoutableService(IContentManager contentManager, IEnumerable slugEventHandlers) { _contentManager = contentManager; + _slugEventHandlers = slugEventHandlers; } public void FixContainedPaths(IRoutableAspect part) { @@ -27,23 +32,47 @@ namespace Orchard.Core.Routable.Services { } } + public static string RemoveDiacritics(string slug) { + string stFormD = slug.Normalize(NormalizationForm.FormD); + StringBuilder sb = new StringBuilder(); + + for (int ich = 0; ich < stFormD.Length; ich++) { + UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]); + if (uc != UnicodeCategory.NonSpacingMark) { + sb.Append(stFormD[ich]); + } + } + + return (sb.ToString().Normalize(NormalizationForm.FormC)); + } + public void FillSlugFromTitle(TModel model) where TModel : IRoutableAspect { if (!string.IsNullOrEmpty(model.Slug) || string.IsNullOrEmpty(model.Title)) return; - var slug = model.Title; - var dissallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s\""\<\>]+"); + FillSlugContext slugContext = new FillSlugContext(model.Title); - slug = dissallowed.Replace(slug, "-"); - slug = slug.Trim('-'); + foreach(ISlugEventHandler slugEventHandler in _slugEventHandlers) { + slugEventHandler.FillingSlugFromTitle(slugContext); + } - if (slug.Length > 1000) - slug = slug.Substring(0, 1000); + if (!slugContext.Adjusted) { + var disallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s\""\<\>]+"); - // dots are not allowed at the begin and the end of routes - slug = slug.Trim('.'); + slugContext.Slug = disallowed.Replace(slugContext.Slug, "-").Trim('-'); - model.Slug = slug.ToLowerInvariant(); + if (slugContext.Slug.Length > 1000) + slugContext.Slug = slugContext.Slug.Substring(0, 1000); + + // dots are not allowed at the begin and the end of routes + slugContext.Slug = RemoveDiacritics(slugContext.Slug.Trim('.').ToLower()); + } + + foreach (ISlugEventHandler slugEventHandler in _slugEventHandlers) { + slugEventHandler.FilledSlugFromTitle(slugContext); + } + + model.Slug = slugContext.Slug; } public string GenerateUniqueSlug(IRoutableAspect part, IEnumerable existingPaths) { diff --git a/src/Orchard.Web/Core/Settings/Migrations.cs b/src/Orchard.Web/Core/Settings/Migrations.cs index 17c0b9561..57d45a144 100644 --- a/src/Orchard.Web/Core/Settings/Migrations.cs +++ b/src/Orchard.Web/Core/Settings/Migrations.cs @@ -90,6 +90,7 @@ namespace Orchard.Core.Settings { .Column("HomePage") .Column("SiteCulture") .Column("ResourceDebugMode", c => c.WithDefault("FromAppSetting")) + .Column("PageSize") ); return 1; diff --git a/src/Orchard.Web/Core/Settings/Models/SiteSettingsPart.cs b/src/Orchard.Web/Core/Settings/Models/SiteSettingsPart.cs index fa6d8fdc3..3e5094699 100644 --- a/src/Orchard.Web/Core/Settings/Models/SiteSettingsPart.cs +++ b/src/Orchard.Web/Core/Settings/Models/SiteSettingsPart.cs @@ -8,28 +8,39 @@ namespace Orchard.Core.Settings.Models { get { return Record.PageTitleSeparator; } set { Record.PageTitleSeparator = value; } } + public string SiteName { get { return Record.SiteName; } set { Record.SiteName = value; } } + public string SiteSalt { get { return Record.SiteSalt; } } + public string SuperUser { get { return Record.SuperUser; } set { Record.SuperUser = value; } } + public string HomePage { get { return Record.HomePage; } set { Record.HomePage = value; } } + public string SiteCulture { get { return Record.SiteCulture; } set { Record.SiteCulture = value; } } + public ResourceDebugMode ResourceDebugMode { get { return Record.ResourceDebugMode; } set { Record.ResourceDebugMode = value; } } + + public int PageSize { + get { return Record.PageSize; } + set { Record.PageSize = value; } + } } } diff --git a/src/Orchard.Web/Core/Settings/Models/SiteSettingsPartRecord.cs b/src/Orchard.Web/Core/Settings/Models/SiteSettingsPartRecord.cs index 2478ff91f..eb87877f5 100644 --- a/src/Orchard.Web/Core/Settings/Models/SiteSettingsPartRecord.cs +++ b/src/Orchard.Web/Core/Settings/Models/SiteSettingsPartRecord.cs @@ -3,12 +3,26 @@ using Orchard.Settings; namespace Orchard.Core.Settings.Models { public class SiteSettingsPartRecord : ContentPartRecord { + public const int DefaultPageSize = 10; + + public SiteSettingsPartRecord() { + PageSize = DefaultPageSize; + } + public virtual string SiteSalt { get; set; } + public virtual string SiteName { get; set; } + public virtual string SuperUser { get; set; } + public virtual string PageTitleSeparator { get; set; } + public virtual string HomePage { get; set; } + public virtual string SiteCulture { get; set; } + public virtual ResourceDebugMode ResourceDebugMode { get; set; } + + public virtual int PageSize { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Core/Settings/ViewModels/SiteSettingsPartViewModel.cs b/src/Orchard.Web/Core/Settings/ViewModels/SiteSettingsPartViewModel.cs index 3c5624ff2..8bbb87d40 100644 --- a/src/Orchard.Web/Core/Settings/ViewModels/SiteSettingsPartViewModel.cs +++ b/src/Orchard.Web/Core/Settings/ViewModels/SiteSettingsPartViewModel.cs @@ -15,8 +15,7 @@ namespace Orchard.Core.Settings.ViewModels { get { return Site.ContentItem.Id; } } - public string PageTitleSeparator - { + public string PageTitleSeparator { get { return Site.Record.PageTitleSeparator; } set { Site.Record.PageTitleSeparator = value; } } @@ -40,5 +39,10 @@ namespace Orchard.Core.Settings.ViewModels { get { return Site.As().ResourceDebugMode; } set { Site.As().ResourceDebugMode = value; } } + + public int PageSize { + get { return Site.As().PageSize; } + set { Site.As().PageSize = value; } + } } } diff --git a/src/Orchard.Web/Core/Settings/Views/EditorTemplates/Parts.Settings.SiteSettingsPart.cshtml b/src/Orchard.Web/Core/Settings/Views/EditorTemplates/Parts.Settings.SiteSettingsPart.cshtml index ba9a67d96..e8d36de86 100644 --- a/src/Orchard.Web/Core/Settings/Views/EditorTemplates/Parts.Settings.SiteSettingsPart.cshtml +++ b/src/Orchard.Web/Core/Settings/Views/EditorTemplates/Parts.Settings.SiteSettingsPart.cshtml @@ -36,4 +36,9 @@ @Html.DropDownList("ResourceDebugMode", resourceDebugMode) @T("Determines whether scripts and stylesheets load in their debuggable or minified form.") +
+ + @Html.TextBoxFor(m => m.PageSize, new { @class = "textMedium" }) + @T("Determines the default number of items that are shown per page.") +
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.Blogs/AdminMenu.cs index d54c11dc2..258b630ee 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/AdminMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/AdminMenu.cs @@ -25,7 +25,7 @@ namespace Orchard.Blogs { var singleBlog = blogCount == 1 ? blogs.ElementAt(0) : null; if (blogCount > 0 && singleBlog == null) { - menu.Add(T("List"), "3", + menu.Add(T("Manage Blogs"), "3", item => item.Action("List", "BlogAdmin", new {area = "Orchard.Blogs"}).Permission(Permissions.MetaListOwnBlogs)); } else if (singleBlog != null) diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs index c9a0686d1..d7ce86253 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs @@ -15,6 +15,8 @@ using Orchard.UI.Navigation; using Orchard.UI.Notify; namespace Orchard.Blogs.Controllers { + using Orchard.Settings; + [ValidateInput(false), Admin] public class BlogAdminController : Controller, IUpdateModel { private readonly IBlogService _blogService; @@ -22,6 +24,7 @@ namespace Orchard.Blogs.Controllers { private readonly IContentManager _contentManager; private readonly ITransactionManager _transactionManager; private readonly IBlogSlugConstraint _blogSlugConstraint; + private readonly ISiteService _siteService; public BlogAdminController( IOrchardServices services, @@ -30,6 +33,7 @@ namespace Orchard.Blogs.Controllers { IContentManager contentManager, ITransactionManager transactionManager, IBlogSlugConstraint blogSlugConstraint, + ISiteService siteService, IShapeFactory shapeFactory) { Services = services; _blogService = blogService; @@ -37,6 +41,7 @@ namespace Orchard.Blogs.Controllers { _contentManager = contentManager; _transactionManager = transactionManager; _blogSlugConstraint = blogSlugConstraint; + _siteService = siteService; T = NullLocalizer.Instance; Shape = shapeFactory; } @@ -147,7 +152,8 @@ namespace Orchard.Blogs.Controllers { return View((object)viewModel); } - public ActionResult Item(int blogId, Pager pager) { + public ActionResult Item(int blogId, PagerParameters pagerParameters) { + Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters); BlogPart blogPart = _blogService.Get(blogId, VersionOptions.Latest).As(); if (blogPart == null) diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs index 5661a51ce..43a78d750 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs @@ -13,6 +13,8 @@ using Orchard.Themes; using Orchard.UI.Navigation; namespace Orchard.Blogs.Controllers { + using Orchard.Settings; + [Themed] public class BlogController : Controller { private readonly IOrchardServices _services; @@ -22,6 +24,7 @@ namespace Orchard.Blogs.Controllers { private readonly IFeedManager _feedManager; private readonly IWorkContextAccessor _workContextAccessor; private readonly IHomePageProvider _routableHomePageProvider; + private readonly ISiteService _siteService; public BlogController( IOrchardServices services, @@ -31,13 +34,15 @@ namespace Orchard.Blogs.Controllers { IFeedManager feedManager, IShapeFactory shapeFactory, IWorkContextAccessor workContextAccessor, - IEnumerable homePageProviders) { + IEnumerable homePageProviders, + ISiteService siteService) { _services = services; _blogService = blogService; _blogPostService = blogPostService; _blogSlugConstraint = blogSlugConstraint; _feedManager = feedManager; _workContextAccessor = workContextAccessor; + _siteService = siteService; _routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name); Logger = NullLogger.Instance; Shape = shapeFactory; @@ -59,7 +64,8 @@ namespace Orchard.Blogs.Controllers { return View((object)viewModel); } - public ActionResult Item(string blogSlug, Pager pager) { + public ActionResult Item(string blogSlug, PagerParameters pagerParameters) { + Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters); var correctedSlug = _blogSlugConstraint.FindSlug(blogSlug); if (correctedSlug == null) return HttpNotFound(); diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs index 90e71d88d..1fc750a75 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Migrations.cs @@ -5,7 +5,7 @@ namespace Orchard.Blogs { public class Migrations : DataMigrationImpl { public int Create() { - SchemaBuilder.CreateTable("BlogPartArchiveRecord", + SchemaBuilder.CreateTable("BlogPartArchiveRecord", table => table .Column("Id", column => column.PrimaryKey().Identity()) .Column("Year") @@ -14,21 +14,21 @@ namespace Orchard.Blogs { .Column("BlogPart_id") ); - SchemaBuilder.CreateTable("BlogPartRecord", + SchemaBuilder.CreateTable("BlogPartRecord", table => table .ContentPartRecord() .Column("Description", c => c.Unlimited()) .Column("PostCount") ); - SchemaBuilder.CreateTable("RecentBlogPostsPartRecord", + SchemaBuilder.CreateTable("RecentBlogPostsPartRecord", table => table .ContentPartRecord() .Column("BlogSlug") .Column("Count") ); - SchemaBuilder.CreateTable("BlogArchivesPartRecord", + SchemaBuilder.CreateTable("BlogArchivesPartRecord", table => table .ContentPartRecord() .Column("BlogSlug", c => c.WithLength(255)) diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs index bd48b5c8a..616086921 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs @@ -123,7 +123,7 @@ namespace Orchard.Blogs.Services { string password) { var user = _membershipService.ValidateUser(userName, password); - _authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null); + _authorizationService.CheckAccess(Permissions.EditOthersBlogPost, user, null); var array = new XRpcArray(); foreach (var blog in _blogService.Get()) { @@ -144,7 +144,7 @@ namespace Orchard.Blogs.Services { int numberOfPosts) { var user = _membershipService.ValidateUser(userName, password); - _authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null); + _authorizationService.CheckAccess(Permissions.EditOthersBlogPost, user, null); var blog = _contentManager.Get(Convert.ToInt32(blogId)); if (blog == null) @@ -166,7 +166,7 @@ namespace Orchard.Blogs.Services { IEnumerable drivers) { var user = _membershipService.ValidateUser(userName, password); - _authorizationService.CheckAccess(Permissions.EditOwnBlogPost, user, null); + _authorizationService.CheckAccess(publish ? Permissions.PublishOthersBlogPost : Permissions.EditOthersBlogPost, user, null); var blog = _contentManager.Get(Convert.ToInt32(blogId)); if (blog == null) @@ -216,7 +216,7 @@ namespace Orchard.Blogs.Services { IEnumerable drivers) { var user = _membershipService.ValidateUser(userName, password); - _authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null); + _authorizationService.CheckAccess(Permissions.EditOthersBlogPost, user, null); var blogPost = _blogPostService.Get(postId, VersionOptions.Latest); if (blogPost == null) @@ -231,15 +231,13 @@ namespace Orchard.Blogs.Services { } private bool MetaWeblogEditPost(int postId, string userName, string password, XRpcStruct content, bool publish, IEnumerable drivers) { - var user = _membershipService.ValidateUser(userName, password); - _authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null); + _authorizationService.CheckAccess(publish ? Permissions.PublishOthersBlogPost : Permissions.EditOthersBlogPost, user, null); var blogPost = _blogPostService.Get(postId, VersionOptions.DraftRequired); if (blogPost == null) throw new ArgumentException(); - var title = content.Optional("title"); var description = content.Optional("description"); var slug = content.Optional("wp_slug"); @@ -259,7 +257,7 @@ namespace Orchard.Blogs.Services { private bool MetaWeblogDeletePost(string appkey, string postId, string userName, string password, bool publish, IEnumerable drivers) { var user = _membershipService.ValidateUser(userName, password); - _authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null); + _authorizationService.CheckAccess(Permissions.DeleteOthersBlogPost, user, null); var blogPost = _blogPostService.Get(Convert.ToInt32(postId), VersionOptions.Latest); if (blogPost == null) diff --git a/src/Orchard.Web/Modules/Orchard.Comments/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Comments/Controllers/AdminController.cs index c5164d4ad..69d543b72 100644 --- a/src/Orchard.Web/Modules/Orchard.Comments/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Comments/Controllers/AdminController.cs @@ -14,12 +14,20 @@ using Orchard.Comments.ViewModels; using Orchard.Comments.Services; namespace Orchard.Comments.Controllers { + using Orchard.Settings; + [ValidateInput(false)] public class AdminController : Controller { private readonly ICommentService _commentService; + private readonly ISiteService _siteService; - public AdminController(IOrchardServices services, ICommentService commentService, IShapeFactory shapeFactory) { + public AdminController( + IOrchardServices services, + ICommentService commentService, + ISiteService siteService, + IShapeFactory shapeFactory) { _commentService = commentService; + _siteService = siteService; Services = services; Logger = NullLogger.Instance; T = NullLocalizer.Instance; @@ -31,7 +39,9 @@ namespace Orchard.Comments.Controllers { public Localizer T { get; set; } dynamic Shape { get; set; } - public ActionResult Index(CommentIndexOptions options, Pager pager) { + public ActionResult Index(CommentIndexOptions options, PagerParameters pagerParameters) { + Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters); + // Default options if (options == null) options = new CommentIndexOptions(); diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.Packaging/AdminMenu.cs index f34d93011..fbfe5565b 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/AdminMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.Packaging/AdminMenu.cs @@ -1,6 +1,7 @@ using Orchard.Environment.Extensions; using Orchard.Localization; using Orchard.UI.Navigation; +using Orchard.Security; namespace Orchard.Packaging { [OrchardFeature("Gallery")] @@ -12,11 +13,14 @@ namespace Orchard.Packaging { public void GetNavigation(NavigationBuilder builder) { builder.Add(T("Gallery"), "30", menu => menu .Add(T("Modules"), "1.0", item => item - .Action("Modules", "Gallery", new { area = "Orchard.Packaging" })) + .Action("Modules", "Gallery", new { area = "Orchard.Packaging" }) + .Permission(StandardPermissions.SiteOwner)) .Add(T("Themes"), "2.0", item => item - .Action("Themes", "Gallery", new { area = "Orchard.Packaging" })) + .Action("Themes", "Gallery", new { area = "Orchard.Packaging" }) + .Permission(StandardPermissions.SiteOwner)) .Add(T("Feeds"), "3.0", item => item - .Action("Sources", "Gallery", new { area = "Orchard.Packaging" }))); + .Action("Sources", "Gallery", new { area = "Orchard.Packaging" }) + .Permission(StandardPermissions.SiteOwner))); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/GalleryController.cs b/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/GalleryController.cs index 57654a990..c07eecccf 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/GalleryController.cs +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/GalleryController.cs @@ -9,6 +9,7 @@ using Orchard.Localization; using Orchard.Logging; using Orchard.Packaging.Services; using Orchard.Packaging.ViewModels; +using Orchard.Security; using Orchard.Themes; using Orchard.UI.Admin; using Orchard.UI.Notify; @@ -26,36 +27,51 @@ namespace Orchard.Packaging.Controllers { public GalleryController( IPackageManager packageManager, IPackagingSourceManager packagingSourceManager, - INotifier notifier) { + INotifier notifier, + IOrchardServices services) { _packageManager = packageManager; _packagingSourceManager = packagingSourceManager; _notifier = notifier; + Services = services; T = NullLocalizer.Instance; Logger = NullLogger.Instance; } + public IOrchardServices Services { get; set; } public Localizer T { get; set; } public ILogger Logger { get; set; } public ActionResult Sources() { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list sources"))) + return new HttpUnauthorizedResult(); + return View(new PackagingSourcesViewModel { Sources = _packagingSourceManager.GetSources(), }); } public ActionResult Remove(int id) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to remove sources"))) + return new HttpUnauthorizedResult(); + _packagingSourceManager.RemoveSource(id); _notifier.Information(T("The feed has been removed successfully.")); return RedirectToAction("Sources"); } public ActionResult AddSource() { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add sources"))) + return new HttpUnauthorizedResult(); + return View(new PackagingAddSourceViewModel()); } [HttpPost] public ActionResult AddSource(string url) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add sources"))) + return new HttpUnauthorizedResult(); + try { if (!String.IsNullOrEmpty(url)) { if (!url.StartsWith("http")) { @@ -96,6 +112,9 @@ namespace Orchard.Packaging.Controllers { } public ActionResult Modules(int? sourceId) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list modules"))) + return new HttpUnauthorizedResult(); + var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault(); var sources = selectedSource != null @@ -123,6 +142,9 @@ namespace Orchard.Packaging.Controllers { } public ActionResult Themes(int? sourceId) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list themes"))) + return new HttpUnauthorizedResult(); + var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault(); var sources = selectedSource != null @@ -138,6 +160,9 @@ namespace Orchard.Packaging.Controllers { } public ActionResult Install(string packageId, string version, int sourceId, string redirectTo) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to install packages"))) + return new HttpUnauthorizedResult(); + var source = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault(); if (source == null) { diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/PackagingServicesController.cs b/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/PackagingServicesController.cs index e51d385f1..08a5abb83 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/PackagingServicesController.cs +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/PackagingServicesController.cs @@ -8,6 +8,7 @@ using Orchard.Environment.Extensions; using Orchard.FileSystems.AppData; using Orchard.Localization; using Orchard.Packaging.Services; +using Orchard.Security; using Orchard.Themes; using Orchard.UI.Admin; using Orchard.UI.Notify; @@ -25,7 +26,8 @@ namespace Orchard.Packaging.Controllers { public PackagingServicesController( IPackageManager packageManager, INotifier notifier, - IAppDataFolderRoot appDataFolderRoot) { + IAppDataFolderRoot appDataFolderRoot, + IOrchardServices services) { _packageManager = packageManager; _notifier = notifier; _appDataFolderRoot = appDataFolderRoot; @@ -34,31 +36,50 @@ namespace Orchard.Packaging.Controllers { } public Localizer T { get; set; } + public IOrchardServices Services { get; set; } public ActionResult AddTheme(string returnUrl) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add themes"))) + return new HttpUnauthorizedResult(); + return View(); } [HttpPost, ActionName("AddTheme")] public ActionResult AddThemePOST(string returnUrl) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add themes"))) + return new HttpUnauthorizedResult(); + return InstallPackage(returnUrl, Request.RawUrl); } [HttpPost, ActionName("RemoveTheme")] public ActionResult RemoveThemePOST(string themeId, string returnUrl, string retryUrl) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to remove themes"))) + return new HttpUnauthorizedResult(); + return UninstallPackage(PackagingSourceManager.ThemesPrefix + themeId, returnUrl, retryUrl); } public ActionResult AddModule(string returnUrl) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add modules"))) + return new HttpUnauthorizedResult(); + return View(); } [HttpPost, ActionName("AddModule")] public ActionResult AddModulePOST(string returnUrl) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add modules"))) + return new HttpUnauthorizedResult(); + return InstallPackage(returnUrl, Request.RawUrl); } public ActionResult InstallPackage(string returnUrl, string retryUrl) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to install packages"))) + return new HttpUnauthorizedResult(); + try { if (Request.Files != null && Request.Files.Count > 0 && @@ -90,6 +111,9 @@ namespace Orchard.Packaging.Controllers { } public ActionResult UninstallPackage(string id, string returnUrl, string retryUrl) { + if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to uninstall packages"))) + return new HttpUnauthorizedResult(); + try { _packageManager.Uninstall(id, HostingEnvironment.MapPath("~/")); diff --git a/src/Orchard.Web/Modules/Orchard.Search/Controllers/SearchController.cs b/src/Orchard.Web/Modules/Orchard.Search/Controllers/SearchController.cs index 5b78dac13..d0cbfef66 100644 --- a/src/Orchard.Web/Modules/Orchard.Search/Controllers/SearchController.cs +++ b/src/Orchard.Web/Modules/Orchard.Search/Controllers/SearchController.cs @@ -15,19 +15,24 @@ using Orchard.Collections; using Orchard.Themes; namespace Orchard.Search.Controllers { + using Orchard.Settings; + [ValidateInput(false), Themed] public class SearchController : Controller { private readonly ISearchService _searchService; private readonly IContentManager _contentManager; + private readonly ISiteService _siteService; public SearchController( IOrchardServices services, - ISearchService searchService, - IContentManager contentManager, + ISearchService searchService, + IContentManager contentManager, + ISiteService siteService, IShapeFactory shapeFactory) { Services = services; _searchService = searchService; _contentManager = contentManager; + _siteService = siteService; T = NullLocalizer.Instance; Logger = NullLogger.Instance; @@ -39,7 +44,8 @@ namespace Orchard.Search.Controllers { public ILogger Logger { get; set; } dynamic Shape { get; set; } - public ActionResult Index(Pager pager, string q = "") { + public ActionResult Index(PagerParameters pagerParameters, string q = "") { + Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters); var searchFields = Services.WorkContext.CurrentSite.As().SearchedFields; IPageOfItems searchHits = new PageOfItems(new ISearchHit[] { }); diff --git a/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs b/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs index 5db72cf02..4e45cd581 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/SetupMode.cs @@ -8,6 +8,7 @@ using Orchard.Commands.Builtin; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; using Orchard.ContentManagement.MetaData.Builders; +using Orchard.Core.Settings.Models; using Orchard.Data.Migration.Interpreters; using Orchard.Data.Providers; using Orchard.Data.Migration; @@ -172,6 +173,11 @@ namespace Orchard.Setup { get { return ResourceDebugMode.FromAppSetting; } set { throw new NotImplementedException(); } } + + public int PageSize { + get { return SiteSettingsPartRecord.DefaultPageSize; } + set { throw new NotImplementedException(); } + } } } } diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Controllers/HomeController.cs b/src/Orchard.Web/Modules/Orchard.Tags/Controllers/HomeController.cs index abfbdfbeb..63cff0658 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Controllers/HomeController.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Controllers/HomeController.cs @@ -4,6 +4,7 @@ using Orchard.ContentManagement; using Orchard.DisplayManagement; using Orchard.Localization; using Orchard.Logging; +using Orchard.Settings; using Orchard.Tags.Services; using Orchard.Tags.ViewModels; using Orchard.Themes; @@ -14,14 +15,17 @@ namespace Orchard.Tags.Controllers { public class HomeController : Controller { private readonly ITagService _tagService; private readonly IContentManager _contentManager; + private readonly ISiteService _siteService; private readonly dynamic _shapeFactory; public HomeController( - ITagService tagService, - IContentManager contentManager, + ITagService tagService, + IContentManager contentManager, + ISiteService siteService, IShapeFactory shapeFactory) { _tagService = tagService; _contentManager = contentManager; + _siteService = siteService; _shapeFactory = shapeFactory; T = NullLocalizer.Instance; } @@ -35,7 +39,9 @@ namespace Orchard.Tags.Controllers { return View(model); } - public ActionResult Search(string tagName, Pager pager) { + public ActionResult Search(string tagName, PagerParameters pagerParameters) { + Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters); + var tag = _tagService.GetTagByName(tagName); if (tag == null) { diff --git a/src/Orchard/Data/Providers/SqlServerDataServicesProvider.cs b/src/Orchard/Data/Providers/SqlServerDataServicesProvider.cs index acce27bd0..a266af81a 100644 --- a/src/Orchard/Data/Providers/SqlServerDataServicesProvider.cs +++ b/src/Orchard/Data/Providers/SqlServerDataServicesProvider.cs @@ -18,7 +18,7 @@ namespace Orchard.Data.Providers { public override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase) { var persistence = MsSqlConfiguration.MsSql2008; if (string.IsNullOrEmpty(_connectionString)) { - throw new NotImplementedException(); + throw new ArgumentException("The connection string is empty"); } persistence = persistence.ConnectionString(_connectionString); return persistence; diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index faed86f55..a85f5d542 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -188,6 +188,7 @@ + diff --git a/src/Orchard/Settings/ISite.cs b/src/Orchard/Settings/ISite.cs index 23f046363..f215673e7 100644 --- a/src/Orchard/Settings/ISite.cs +++ b/src/Orchard/Settings/ISite.cs @@ -2,7 +2,7 @@ namespace Orchard.Settings { /// - /// Interface provided by the "settings" model. + /// Interface provided by the "settings" model. /// public interface ISite : IContent { string PageTitleSeparator { get; } @@ -12,5 +12,6 @@ namespace Orchard.Settings { string HomePage { get; set; } string SiteCulture { get; set; } ResourceDebugMode ResourceDebugMode { get; set; } + int PageSize { get; set; } } } diff --git a/src/Orchard/UI/Navigation/Pager.cs b/src/Orchard/UI/Navigation/Pager.cs index 2adaef763..9783e6ed8 100644 --- a/src/Orchard/UI/Navigation/Pager.cs +++ b/src/Orchard/UI/Navigation/Pager.cs @@ -1,22 +1,49 @@ -namespace Orchard.UI.Navigation { +using Orchard.Settings; + +namespace Orchard.UI.Navigation { public class Pager { - private const int PageDefault = 1; - public const int PageSizeDefault = 10; - private int _pageSize; - private int _size; + /// + /// The default page number. + /// + public const int PageDefault = 1; - public int Page { - get { return _pageSize > 0 ? _pageSize : PageDefault; } - set { _pageSize = value; } + /// + /// Constructs a new pager. + /// + /// The site settings. + /// The pager parameters. + public Pager(ISite site, PagerParameters pagerParameters) + : this(site, pagerParameters.Page, pagerParameters.PageSize) { } - public int PageSize { - get { return _size > 0 ? _size : PageSizeDefault; } - set { _size = value; } + /// + /// Constructs a new pager. + /// + /// The site settings. + /// The page parameter. + /// The page size parameter. + public Pager(ISite site, int? page, int? pageSize) { + Page = (int) (page != null ? (page > 0 ? page : PageDefault) : PageDefault); + PageSize = pageSize ?? site.PageSize; } + /// + /// Gets or sets the current page number or the default page number if none is specified. + /// + public int Page { get; set; } + + /// + /// Gets or sets the current page size or the site default size if none is specified. + /// + public int PageSize { get; set; } + + /// + /// Gets the current page start index. + /// + /// The current page number. + /// The index in which the page starts. public int GetStartIndex(int? page = null) { - return ((page ?? Page) - 1)*PageSize; + return ((page ?? Page) - PageDefault) * PageSize; } } } \ No newline at end of file diff --git a/src/Orchard/UI/Navigation/PagerParameters.cs b/src/Orchard/UI/Navigation/PagerParameters.cs new file mode 100644 index 000000000..efefed885 --- /dev/null +++ b/src/Orchard/UI/Navigation/PagerParameters.cs @@ -0,0 +1,13 @@ +namespace Orchard.UI.Navigation { + public class PagerParameters { + /// + /// Gets or sets the current page number or null if none specified. + /// + public int? Page { get; set; } + + /// + /// Gets or sets the current page size or null if none specified. + /// + public int? PageSize { get; set; } + } +}