Merge branch '1.10.x' into dev

# Conflicts:
#	src/Orchard.Web/Core/Navigation/Views/EditorTemplates/Parts.MenuWidget.Edit.cshtml
#	src/Orchard.Web/Modules/Orchard.Layouts/Views/EditorTemplates/Elements.Menu.cshtml
#	src/Orchard.Web/Modules/Orchard.Localization/Services/LocalizationService.cs
#	src/Orchard.Web/Modules/Orchard.MediaLibrary/MediaFileName/MediaFileNameDriver.cs
This commit is contained in:
Benedek Farkas 2019-08-23 20:36:03 +02:00
commit 93c6fbef86
23 changed files with 237 additions and 259 deletions
src
Orchard.Web
Core/Navigation/Views/EditorTemplates
Modules
Orchard.DynamicForms
Orchard.Layouts/Views/EditorTemplates
Orchard.Localization/Services
Orchard.MediaLibrary/MediaFileName
Orchard.Projections
Orchard.Roles
Orchard.Rules/Providers
Orchard.Workflows/Forms
Orchard/Validation

View File

@ -1,51 +1,51 @@
@model Orchard.Core.Navigation.ViewModels.MenuWidgetViewModel
@using Orchard.ContentManagement
@using Orchard.Core.Navigation.Models;
<fieldset>
@Html.LabelFor(m => m.CurrentMenuId, T("For Menu"))
<select id="@Html.FieldIdFor(m => m.CurrentMenuId)" name="@Html.FieldNameFor(m => m.CurrentMenuId)">
@foreach(ContentItem menu in Model.Menus) {
@Html.SelectOption(Model.CurrentMenuId, menu.Id, Html.ItemDisplayText(menu, false).ToString())
}
</select>
<span class="hint">@T("Select which menu you want to display")</span>
</fieldset>
<fieldset>
<label for="@Html.FieldIdFor(m => m.StartLevel)">@T("Start Level")</label>
@Html.TextBoxFor(m => m.StartLevel, new { @class = "text small" })
<span class="hint">@T("The level the menu should start at.")</span>
</fieldset>
<fieldset>
<label for="@Html.FieldIdFor(m => m.StopLevel)">@T("Levels to display")</label>
@Html.TextBoxFor(m => m.StopLevel, new { @class = "text small" })
<span class="hint">@T("The number of levels to display, \"0\" meaning all levels.")</span>
</fieldset>
<fieldset>
@Html.EditorFor(m => m.Breadcrumb)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Breadcrumb)">@T("Display as Breadcrumb")</label>
<span class="hint">@T("Check to render the path to the current content item.")</span>
</fieldset>
<div data-controllerid="@Html.FieldIdFor(m => m.Breadcrumb)">
<fieldset>
@Html.LabelFor(m => m.CurrentMenuId, T("For Menu"))
<select id="@Html.FieldIdFor(m => m.CurrentMenuId)" name="@Html.FieldNameFor(m => m.CurrentMenuId)">
@foreach(ContentItem menu in Model.Menus) {
@Html.SelectOption(Model.CurrentMenuId, menu.Id, Html.ItemDisplayText(menu, false).ToString())
}
</select>
<span class="hint">@T("Select which menu you want to display")</span>
@Html.EditorFor(m => m.AddHomePage)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.AddHomePage)">@T("Add the home page as the first element")</label>
<span class="hint">@T("Check to render the home page as the first element of the breadcrumb.")</span>
</fieldset>
<fieldset>
<label for="@Html.FieldIdFor(m => m.StartLevel)">@T("Start Level")</label>
@Html.TextBoxFor(m => m.StartLevel, new { @class = "text small" })
<span class="hint">@T("The level the menu should start at.")</span>
@Html.EditorFor(m => m.AddCurrentPage)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.AddCurrentPage)">@T("Add the current content item as the last element")</label>
<span class="hint">@T("Check to render the current content item as the last element.")</span>
</fieldset>
</div>
<fieldset>
<label for="@Html.FieldIdFor(m => m.StopLevel)">@T("Levels to display")</label>
@Html.TextBoxFor(m => m.StopLevel, new { @class = "text small" })
<span class="hint">@T("The number of levels to display, \"0\" meaning all levels.")</span>
</fieldset>
<fieldset>
@Html.EditorFor(m => m.Breadcrumb)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Breadcrumb)">@T("Display as Breadcrumb")</label>
<span class="hint">@T("Check to render the path to the current content item.")</span>
</fieldset>
<div data-controllerid="@Html.FieldIdFor(m => m.Breadcrumb)">
<fieldset>
@Html.EditorFor(m => m.AddHomePage)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.AddHomePage)">@T("Add the home page as the first element")</label>
<span class="hint">@T("Check to render the home page as the first element of the breadcrumb.")</span>
</fieldset>
<fieldset>
@Html.EditorFor(m => m.AddCurrentPage)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.AddCurrentPage)">@T("Add the current content item as the last element")</label>
<span class="hint">@T("Check to render the current content item as the last element.")</span>
</fieldset>
</div>
<fieldset>
@Html.EditorFor(m => m.ShowFullMenu)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.ShowFullMenu)">@T("No filter on selected page")</label>
<span class="hint">@T("Check for the menu to be displayed without filtering the selected current page.")</span>
</fieldset>
<fieldset>
@Html.EditorFor(m => m.ShowFullMenu)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.ShowFullMenu)">@T("No filter on selected page")</label>
<span class="hint">@T("Check for the menu to be displayed without filtering the selected current page.")</span>
</fieldset>

View File

@ -3,12 +3,14 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
using Orchard.ContentManagement;
using Orchard.DynamicForms.Elements;
using Orchard.Environment.Extensions;
using Orchard.Layouts.Framework.Display;
using Orchard.Layouts.Framework.Drivers;
using Orchard.Layouts.Helpers;
using Orchard.Layouts.Services;
using Orchard.Taxonomies.Models;
using Orchard.Taxonomies.Services;
using Orchard.Tokens;
using DescribeContext = Orchard.Forms.Services.DescribeContext;
@ -18,11 +20,17 @@ namespace Orchard.DynamicForms.Drivers {
public class TaxonomyElementDriver : FormsElementDriver<Taxonomy> {
private readonly ITaxonomyService _taxonomyService;
private readonly ITokenizer _tokenizer;
private readonly IContentManager _contentManager;
public TaxonomyElementDriver(IFormsBasedElementServices formsServices, ITaxonomyService taxonomyService, ITokenizer tokenizer)
public TaxonomyElementDriver(
IFormsBasedElementServices formsServices,
ITaxonomyService taxonomyService,
ITokenizer tokenizer,
IContentManager contentManager)
: base(formsServices) {
_taxonomyService = taxonomyService;
_tokenizer = tokenizer;
_contentManager = contentManager;
}
protected override EditorResult OnBuildEditor(Taxonomy element, ElementEditorContext context) {
@ -146,6 +154,24 @@ namespace Orchard.DynamicForms.Drivers {
context.ElementShape.Metadata.Alternates.Add(String.Format("Elements_{0}_{1}__{2}", typeName, displayType, element.InputType));
}
protected override void OnExporting(Taxonomy element, ExportElementContext context) {
var taxonomy = _contentManager.Get<TaxonomyPart>(element.TaxonomyId ?? 0);
if (taxonomy == null) return;
var taxonomyIdentity = _contentManager.GetItemMetadata(taxonomy)?.Identity?.ToString();
if (string.IsNullOrEmpty(taxonomyIdentity)) context.ExportableData["TaxonomyId"] = taxonomyIdentity;
}
protected override void OnImportCompleted(Taxonomy element, ImportElementContext context) {
var taxonomyIdentity = context.ExportableData.Get("TaxonomyId");
var taxonomy = string.IsNullOrEmpty(taxonomyIdentity) ? context.Session.GetItemFromSession(taxonomyIdentity) : null;
if (taxonomy != null) element.TaxonomyId = taxonomy.Id;
}
private IEnumerable<SelectListItem> GetTermOptions(Taxonomy element, string displayType, int? taxonomyId, IDictionary<string, object> tokenData) {
var optionLabel = element.OptionLabel;
var runtimeValues = GetRuntimeValues(element);

View File

@ -1,94 +0,0 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using Orchard.DynamicForms.Elements;
//using Orchard.DynamicForms.Helpers;
//using Orchard.DynamicForms.Services;
//using Orchard.DynamicForms.Services.Models;
//using Orchard.DynamicForms.ViewModels;
//using Orchard.Forms.Services;
//using Orchard.Layouts.Framework.Display;
//using Orchard.Layouts.Framework.Drivers;
//using Orchard.Layouts.Helpers;
//namespace Orchard.DynamicForms.Drivers {
// public class ValidationElementDriver : ElementDriver<FormElement> {
// private readonly IValidationManager _validationManager;
// private readonly IFormManager _formManager;
// public ValidationElementDriver(IValidationManager validationManager, IFormManager formManager) {
// _validationManager = validationManager;
// _formManager = formManager;
// }
// protected override EditorResult OnBuildEditor(FormElement element, ElementEditorContext context) {
// var validatorNames = element.ValidatorNames.ToArray();
// var validators = new FieldValidationSettingsViewModel {
// Validators = _validationManager.GetValidatorsByNames(validatorNames).Select(x => new FieldValidationSettingViewModel() {
// Name = x.Name,
// SettingsEditor = BuildSettingsEditor(context, x)
// }).ToList()
// };
// if (context.Updater != null) {
// var viewModel = new FieldValidationSettingsViewModel();
// if (context.Updater.TryUpdateModel(viewModel, null, null, null)) {
// if (viewModel.Validators != null) {
// foreach (var validatorModel in viewModel.Validators) {
// var validator = validators.Validators.SingleOrDefault(x => x.Name == validatorModel.Name);
// if (validator == null)
// continue;
// validator.Enabled = validatorModel.Enabled;
// validator.CustomValidationMessage = validatorModel.CustomValidationMessage;
// }
// }
// validators.ShowValidationMessage = viewModel.ShowValidationMessage;
// }
// }
// // Fetch validation descriptors.
// foreach (var validator in validators.Validators) {
// validator.Descriptor = _validationManager.GetValidatorByName(validator.Name);
// }
// var validatorsEditor = context.ShapeFactory.EditorTemplate(TemplateName: "Validators", Model: validators);
// validatorsEditor.Metadata.Position = "Validation:10";
// return Editor(context, validatorsEditor);
// }
// protected override void OnDisplaying(FormElement element, ElementDisplayingContext context) {
// if (context.DisplayType == "Design" || element.Form == null)
// return;
// if (element.Form.EnableClientValidation != true) {
// context.ElementShape.ClientValidationAttributes = new Dictionary<string, string>();
// return;
// }
// var clientAttributes = new Dictionary<string, string> {
// {"data-val", "true"}
// };
// foreach (var validatorSetting in element.ValidationSettings.Validators.Enabled()) {
// var validatorDescriptor = _validationManager.GetValidatorByName(validatorSetting.Name);
// var clientValidationRegistrationContext = new ClientValidationRegistrationContext(element, validatorSetting, validatorDescriptor);
// validatorDescriptor.ClientAttributes(clientValidationRegistrationContext);
// clientAttributes.Combine(clientValidationRegistrationContext.ClientAttributes);
// }
// context.ElementShape.ClientValidationAttributes = clientAttributes;
// }
// private dynamic BuildSettingsEditor(ElementEditorContext context, ValidatorDescriptor validatorDescriptor) {
// if (String.IsNullOrWhiteSpace(validatorDescriptor.SettingsFormName))
// return null;
// return _formManager.Bind(_formManager.Build(validatorDescriptor.SettingsFormName), context.ValueProvider);
// }
// }
//}

View File

@ -273,7 +273,6 @@
<Compile Include="Validators\Settings\TextFieldValidationSettings.cs" />
<Compile Include="Services\Models\ValidationSettingsBase.cs" />
<Compile Include="Services\Models\FormEventContext.cs" />
<Compile Include="Drivers\ValidationElementDriver.cs" />
<Compile Include="Drivers\BindingsElementDriver.cs" />
<Compile Include="Drivers\TaxonomyElementDriver.cs" />
<Compile Include="Drivers\HiddenFieldElementDriver.cs" />

View File

@ -10,7 +10,7 @@ namespace Orchard.DynamicForms.Tokens {
.Token("Field:*", T("Field:<field name>"), T("The posted field value to access."), "Text")
.Token("IsValid:*", T("IsValid:<field name>"), T("The posted field validation status."))
.Token("CreatedContent", T("CreatedContent"), T("Id of the Content Item created by the form."))
;
.Token("FormName", T("FormName"), T("The name of the form posted."));
}
public void Evaluate(EvaluateContext context) {
@ -19,7 +19,8 @@ namespace Orchard.DynamicForms.Tokens {
.Chain(FilterChainParam, "Text", GetFieldValue)
.Token(token => token.StartsWith("IsValid:", StringComparison.OrdinalIgnoreCase) ? token.Substring("IsValid:".Length) : null, GetFieldValidationStatus)
.Token("CreatedContent", GetCreatedContent)
.Chain("CreatedContent", "Content", GetCreatedContent);
.Chain("CreatedContent", "Content", GetCreatedContent)
.Token("FormName", GetFormName);
}
private static Tuple<string, string> FilterChainParam(string token) {
@ -39,9 +40,12 @@ namespace Orchard.DynamicForms.Tokens {
return context.ModelState.IsValidField(fieldName);
}
private object GetCreatedContent(FormSubmissionTokenContext context)
{
private object GetCreatedContent(FormSubmissionTokenContext context) {
return context.CreatedContent;
}
private string GetFormName(FormSubmissionTokenContext context) {
return context.Form.Name;
}
}
}

View File

@ -1,7 +1,9 @@
@model Orchard.Layouts.ViewModels.MenuEditorViewModel
@{
var menuOptions = Model.Menus.Select(x => new SelectListItem {Text = Html.ItemDisplayText(x).ToString(), Value = x.Id.ToString(), Selected = x.Id == Model.CurrentMenuId});
}
<fieldset>
@Html.LabelFor(m => m.CurrentMenuId, T("For Menu"))
@Html.DropDownListFor(m => m.CurrentMenuId, menuOptions)

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.Localization.Models;
@ -9,56 +8,55 @@ namespace Orchard.Localization.Services {
private readonly IContentManager _contentManager;
private readonly ICultureManager _cultureManager;
public LocalizationService(IContentManager contentManager, ICultureManager cultureManager) {
_contentManager = contentManager;
_cultureManager = cultureManager;
}
LocalizationPart ILocalizationService.GetLocalizedContentItem(IContent content, string culture) {
public LocalizationPart GetLocalizedContentItem(IContent content, string culture) {
// Warning: Returns only the first of same culture localizations.
return ((ILocalizationService)this).GetLocalizedContentItem(content, culture, null);
return GetLocalizedContentItem(content, culture, null);
}
LocalizationPart ILocalizationService.GetLocalizedContentItem(IContent content, string culture, VersionOptions versionOptions) {
public LocalizationPart GetLocalizedContentItem(IContent content, string culture, VersionOptions versionOptions) {
var cultureRecord = _cultureManager.GetCultureByName(culture);
if (cultureRecord == null)
return null;
if (cultureRecord == null) return null;
var localized = content.As<LocalizationPart>();
if (localized == null)
return null;
if (localized == null) return null;
if (localized.Culture.Culture == culture)
return localized;
if (localized?.Culture.Culture == culture) return localized;
return ((ILocalizationService)this).GetLocalizations(content, versionOptions).FirstOrDefault(x=>x.Culture.Id == cultureRecord.Id);
return GetLocalizations(content, versionOptions).FirstOrDefault(x => x.Culture.Id == cultureRecord.Id);
}
string ILocalizationService.GetContentCulture(IContent content) {
public string GetContentCulture(IContent content) {
var localized = content.As<LocalizationPart>();
return localized != null && localized.Culture != null
? localized.Culture.Culture
: _cultureManager.GetSiteCulture();
return localized?.Culture == null ?
_cultureManager.GetSiteCulture() :
localized.Culture.Culture;
}
void ILocalizationService.SetContentCulture(IContent content, string culture) {
public void SetContentCulture(IContent content, string culture) {
var localized = content.As<LocalizationPart>();
if (localized == null)
return;
if (localized == null) return;
localized.Culture = _cultureManager.GetCultureByName(culture);
}
IEnumerable<LocalizationPart> ILocalizationService.GetLocalizations(IContent content) {
public IEnumerable<LocalizationPart> GetLocalizations(IContent content) {
// Warning: May contain more than one localization of the same culture.
return ((ILocalizationService)this).GetLocalizations(content, null);
return GetLocalizations(content, null);
}
IEnumerable<LocalizationPart> ILocalizationService.GetLocalizations(IContent content, VersionOptions versionOptions) {
if (content.ContentItem.Id == 0)
return Enumerable.Empty<LocalizationPart>();
public IEnumerable<LocalizationPart> GetLocalizations(IContent content, VersionOptions versionOptions) {
if (content.ContentItem.Id == 0) return Enumerable.Empty<LocalizationPart>();
var localized = content.As<LocalizationPart>();
IContentQuery<LocalizationPart> query;
if (content.ContentItem.TypeDefinition.Parts.Any(x => x.PartDefinition.Name == "TermPart")) { // terms translations can be contained on different TermContentType linked to taxonomies translations
@ -78,12 +76,11 @@ namespace Orchard.Localization.Services {
int masterContentItemId = localized.MasterContentItem.ContentItem.Id;
query = query.Where<LocalizationPartRecord>(l =>
l.Id != contentItemId // Exclude the content
&& (l.Id == masterContentItemId || l.MasterContentItemId == masterContentItemId));
l.Id != contentItemId && // Exclude the content
(l.Id == masterContentItemId || l.MasterContentItemId == masterContentItemId));
}
else {
query = query.Where<LocalizationPartRecord>(l =>
l.MasterContentItemId == contentItemId);
query = query.Where<LocalizationPartRecord>(l => l.MasterContentItemId == contentItemId);
}
// Warning: May contain more than one localization of the same culture.

View File

@ -61,9 +61,12 @@ namespace Orchard.MediaLibrary.MediaFileName
try {
_mediaLibraryService.RenameFile(part.FolderPath, priorFileName, model.FileName);
part.FileName = model.FileName;
_notifier.Add(NotifyType.Success, T("File '{0}' was renamed to '{1}'", priorFileName, model.FileName));
}
catch (OrchardException) {
updater.AddModelError("MediaFileNameEditorSettings.FileName", T("Unable to rename file. Invalid Windows file path."));
}
catch (Exception) {
updater.AddModelError("MediaFileNameEditorSettings.FileName", T("Unable to rename file"));
}

View File

@ -103,7 +103,7 @@ namespace Orchard.Projections.Providers.Layouts {
}
}
public class GridLayoutFormsValitator : FormHandler {
public class GridLayoutFormsValidator : FormHandler {
public Localizer T { get; set; }
public override void Validating(ValidatingContext context) {

View File

@ -65,7 +65,7 @@ namespace Orchard.Projections.Providers.Layouts {
}
}
public class ListLayoutFormsValitator : FormHandler {
public class ListLayoutFormsValidator : FormHandler {
public Localizer T { get; set; }
public override void Validating(ValidatingContext context) {

View File

@ -42,7 +42,7 @@ namespace Orchard.Projections.Providers.SortCriteria {
}
}
public class SortCriterionFormValitator : FormHandler {
public class SortCriterionFormValidator : FormHandler {
public Localizer T { get; set; }
public override void Validating(ValidatingContext context) {

View File

@ -43,7 +43,6 @@ namespace Orchard.Projections.ViewModels {
public bool HideEmpty { get; set; }
public bool RewriteOutput { get; set; }
[StringLength(255)]
public string RewriteText { get; set; }
public bool StripHtmlTags { get; set; }
public bool TrimLength { get; set; }

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using Orchard.Environment.Extensions;
using Orchard.Localization;
using Orchard.Security;
using Orchard.Roles.Models;
using Orchard.Workflows.Models;
using Orchard.Workflows.Services;
@ -28,7 +28,7 @@ namespace Orchard.Roles.Activities {
}
public override LocalizedString Description {
get { return T("Whether the current user is in a specific role."); }
get { return T("Whether the current user is in a specific role."); }
}
public override string Form {
@ -36,7 +36,7 @@ namespace Orchard.Roles.Activities {
}
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) {
return new[] {T("Yes"), T("No")};
return new[] { T("Yes"), T("No") };
}
public override bool CanExecute(WorkflowContext workflowContext, ActivityContext activityContext) {
@ -44,51 +44,16 @@ namespace Orchard.Roles.Activities {
}
public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) {
if (UserIsInRole(activityContext)) {
yield return T("Yes");
}
else {
yield return T("No");
}
yield return _workContextAccessor.GetContext().CurrentUser.UserIsInRole(GetRoles(activityContext)) ? T("Yes") : T("No");
}
private bool UserIsInRole(ActivityContext context) {
// checking if user is in an accepted role
var workContext = _workContextAccessor.GetContext();
var user = workContext.CurrentUser;
var roles = GetRoles(context);
return UserIsInRole(user, roles);
}
public static bool UserIsInRole(IUser user, IEnumerable<string> roles) {
bool isInRole = false;
if (user == null) {
isInRole = roles.Contains("Anonymous");
}
else {
dynamic dynUser = user.ContentItem;
if (dynUser.UserRolesPart != null) {
IEnumerable<string> userRoles = dynUser.UserRolesPart.Roles;
isInRole = userRoles.Any(roles.Contains);
}
}
return isInRole;
}
private IEnumerable<string> GetRoles(ActivityContext context) {
string roles = context.GetState<string>("Roles");
if (String.IsNullOrEmpty(roles)) {
return Enumerable.Empty<string>();
}
return roles.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList();
return string.IsNullOrEmpty(roles) ?
Enumerable.Empty<string>() :
roles.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList();
}
}
}

View File

@ -1,9 +1,8 @@
using Orchard.ContentManagement;
using System;
using System.Linq;
using Orchard.Events;
using Orchard.Roles.Models;
using Orchard.Security;
using System;
using System.Linq;
namespace Orchard.Roles.Conditions {
public interface IConditionProvider : IEventHandler {
@ -18,19 +17,14 @@ namespace Orchard.Roles.Conditions {
}
public void Evaluate(dynamic evaluationContext) {
if (!String.Equals(evaluationContext.FunctionName, "role", StringComparison.OrdinalIgnoreCase)) {
if (!string.Equals(evaluationContext.FunctionName, "role", StringComparison.OrdinalIgnoreCase)) {
return;
}
var user = _authenticationService.GetAuthenticatedUser();
if (user == null) {
evaluationContext.Result = false;
return;
}
var roles = ((object[])evaluationContext.Arguments).Cast<string>();
var userRoles = user.As<IUserRoles>();
evaluationContext.Result = userRoles != null && userRoles.Roles.Intersect(roles).Any();
evaluationContext.Result = user.UserIsInRole(roles);
}
}
}

View File

@ -0,0 +1,12 @@
using System.Collections.Generic;
namespace Orchard.Roles.Constants {
public static class SystemRoles {
public const string Anonymous = nameof(Anonymous);
public const string Authenticated = nameof(Authenticated);
public static IEnumerable<string> GetSystemRoles() {
return new List<string> { Anonymous, Authenticated };
}
}
}

View File

@ -0,0 +1,61 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.Roles.Constants;
using Orchard.Security;
namespace Orchard.Roles.Models {
public static class UserRolesExtensions {
/// <summary>
/// Determines whether the given User has any of the provided list of Roles.
/// </summary>
/// <param name="user">The User to examine.</param>
/// <param name="roles">The list of Roles to compare to User's Roles with.</param>
/// <returns>True if the User has any of the provided Roles.</returns>
public static bool UserIsInRole(this IUser user, IEnumerable<string> roles) {
return UserIsInRole(user.As<UserRolesPart>(), roles);
}
/// <summary>
/// Determines whether the given User has any of the provided list of Roles.
/// </summary>
/// <param name="user">The User to examine.</param>
/// <param name="roles">The list of Roles to compare to User's Roles with.</param>
/// <returns>True if the User has any of the provided Roles.</returns>
public static bool UserIsInRole(this UserRolesPart userRolesPart, IEnumerable<string> roles) {
if (!roles?.Any() ?? false) return false;
return userRolesPart == null ?
roles.Contains(SystemRoles.Anonymous) :
roles.Contains(SystemRoles.Authenticated) || userRolesPart.Roles.Any(roles.Contains);
}
/// <summary>
/// Returns the list of Roles the User has, including the ones
/// that are not assignable (Anonymous or Authenticated).
/// </summary>
/// <param name="user">The User whose Roles are to be retrieved.</param>
/// <returns>The User's list of Roles.</returns>
public static IEnumerable<string> GetRuntimeUserRoles(this IUser user) {
return GetRuntimeUserRoles(user.As<UserRolesPart>());
}
/// <summary>
/// Returns the list of Roles the User has, including the ones
/// that are not assignable (Anonymous or Authenticated).
/// </summary>
/// <param name="user">The UserRolesPart of the User whose Roles are to be retrieved.</param>
/// <returns>The User's list of Roles.</returns>
public static IEnumerable<string> GetRuntimeUserRoles(this UserRolesPart userRolesPart) {
var roles = new List<string>();
if (userRolesPart == null) roles.Add(SystemRoles.Anonymous);
else {
roles.Add(SystemRoles.Authenticated);
roles.AddRange(userRolesPart.Roles);
}
return roles;
}
}
}

View File

@ -7,6 +7,8 @@ using Orchard.Data.Migration;
using Orchard.Roles.Models;
using Orchard.Roles.Services;
using Orchard.Security;
using Orchard.Roles.Constants;
using ContentsPermissions = Orchard.Core.Contents.Permissions;
namespace Orchard.Roles {
public class RolesDataMigration : DataMigrationImpl {
@ -58,32 +60,32 @@ namespace Orchard.Roles {
public int UpdateFrom1() {
// creates default permissions for Orchard v1.4 instances and earlier
_roleService.CreatePermissionForRole("Anonymous", Orchard.Core.Contents.Permissions.ViewContent.Name);
_roleService.CreatePermissionForRole("Authenticated", Orchard.Core.Contents.Permissions.ViewContent.Name);
_roleService.CreatePermissionForRole(SystemRoles.Anonymous, ContentsPermissions.ViewContent.Name);
_roleService.CreatePermissionForRole(SystemRoles.Authenticated, ContentsPermissions.ViewContent.Name);
return 2;
}
public int UpdateFrom2() {
//Assigns the "Create Permission" to all roles able to create contents
var contentEditPermissions = new[] {
Core.Contents.Permissions.EditContent,
Core.Contents.Permissions.EditOwnContent
ContentsPermissions.EditContent,
ContentsPermissions.EditOwnContent
};
var dynamicPermissions = new Orchard.Core.Contents.DynamicPermissions(_contentDefinitionManager);
var dynamicPermissions = new DynamicPermissions(_contentDefinitionManager);
var securableTypes = _contentDefinitionManager.ListTypeDefinitions()
.Where(ctd => ctd.Settings.GetModel<ContentTypeSettings>().Securable);
var permissionTemplates = Core.Contents.DynamicPermissions.PermissionTemplates;
var permissionTemplates = DynamicPermissions.PermissionTemplates;
List<object> dynContentPermissions = new List<object>();
foreach (var typeDefinition in securableTypes) {
dynContentPermissions.Add(new {
Permission = DynamicPermissions.CreateDynamicPermission(permissionTemplates[Core.Contents.Permissions.EditContent.Name], typeDefinition),
CreatePermission = DynamicPermissions.CreateDynamicPermission(permissionTemplates[Core.Contents.Permissions.CreateContent.Name], typeDefinition)
Permission = DynamicPermissions.CreateDynamicPermission(permissionTemplates[ContentsPermissions.EditContent.Name], typeDefinition),
CreatePermission = DynamicPermissions.CreateDynamicPermission(permissionTemplates[ContentsPermissions.CreateContent.Name], typeDefinition)
});
dynContentPermissions.Add(new {
Permission = DynamicPermissions.CreateDynamicPermission(permissionTemplates[Core.Contents.Permissions.EditOwnContent.Name], typeDefinition),
CreatePermission = DynamicPermissions.CreateDynamicPermission(permissionTemplates[Core.Contents.Permissions.CreateContent.Name], typeDefinition)
Permission = DynamicPermissions.CreateDynamicPermission(permissionTemplates[ContentsPermissions.EditOwnContent.Name], typeDefinition),
CreatePermission = DynamicPermissions.CreateDynamicPermission(permissionTemplates[ContentsPermissions.CreateContent.Name], typeDefinition)
});
}
var roles = _roleService.GetRoles();
@ -91,13 +93,13 @@ namespace Orchard.Roles {
var existingPermissionsNames = role.RolesPermissions.Select(x => x.Permission.Name).ToList();
var checkForDynamicPermissions = true;
var updateRole = false;
if (existingPermissionsNames.Any(x => x == Core.Contents.Permissions.CreateContent.Name)) {
if (existingPermissionsNames.Any(x => x == ContentsPermissions.CreateContent.Name)) {
continue; // Skipping this role cause it already has the Create content permission
}
var simulation = UserSimulation.Create(role.Name);
foreach (var contentEditPermission in contentEditPermissions) {
if (_authorizationService.TryCheckAccess(contentEditPermission, simulation, null)) {
existingPermissionsNames.Add(Core.Contents.Permissions.CreateContent.Name);
existingPermissionsNames.Add(ContentsPermissions.CreateContent.Name);
checkForDynamicPermissions = false;
updateRole = true;
break;

View File

@ -105,6 +105,7 @@
<Compile Include="Activities\UserTaskActivity.cs" />
<Compile Include="AdminMenu.cs" />
<Compile Include="Commands\RoleCommands.cs" />
<Compile Include="Constants\SystemRoles.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="Drivers\UserTaskDriver.cs" />
<Compile Include="Events\IRoleEventHandler.cs" />
@ -118,6 +119,7 @@
<Compile Include="Events\UserAddedContext.cs" />
<Compile Include="Events\UserRemovedContext.cs" />
<Compile Include="Events\UserRoleContext.cs" />
<Compile Include="Extensions\UserRolesExtensions.cs" />
<Compile Include="Forms\SelectRolesForms.cs" />
<Compile Include="Forms\UserTaskForms.cs" />
<Compile Include="Recipes\Builders\RolesStep.cs" />

View File

@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.ContentManagement;
using Orchard.Roles.Constants;
using Orchard.Roles.Models;
using Orchard.Security;
using Orchard.Security.Permissions;
@ -13,8 +14,6 @@ namespace Orchard.Roles.Services {
private readonly IRoleService _roleService;
private readonly IWorkContextAccessor _workContextAccessor;
private readonly IAuthorizationServiceEventHandler _authorizationServiceEventHandler;
private static readonly string[] AnonymousRole = new[] { "Anonymous" };
private static readonly string[] AuthenticatedRole = new[] { "Authenticated" };
public RolesBasedAuthorizationService(IRoleService roleService, IWorkContextAccessor workContextAccessor, IAuthorizationServiceEventHandler authorizationServiceEventHandler) {
_roleService = roleService;
@ -57,22 +56,22 @@ namespace Orchard.Roles.Services {
var grantingNames = PermissionNames(context.Permission, Enumerable.Empty<string>()).Distinct().ToArray();
// determine what set of roles should be examined by the access check
IEnumerable<string> rolesToExamine;
var rolesToExamine = new List<string>();
if (context.User == null) {
rolesToExamine = AnonymousRole;
rolesToExamine.Add(SystemRoles.Anonymous);
}
else if (context.User.Has<IUserRoles>()) {
// the current user is not null, so get his roles and add "Authenticated" to it
rolesToExamine = context.User.As<IUserRoles>().Roles;
rolesToExamine = context.User.As<IUserRoles>().Roles.ToList();
// when it is a simulated anonymous user in the admin
if (!rolesToExamine.Contains(AnonymousRole[0])) {
rolesToExamine = rolesToExamine.Concat(AuthenticatedRole);
if (!rolesToExamine.Contains(SystemRoles.Anonymous)) {
rolesToExamine.Add(SystemRoles.Authenticated);
}
}
else {
// the user is not null and has no specific role, then it's just "Authenticated"
rolesToExamine = AuthenticatedRole;
rolesToExamine.Add(SystemRoles.Authenticated);
}
foreach (var role in rolesToExamine) {

View File

@ -1,26 +1,31 @@
@using Orchard.Roles.Constants
@using Orchard.Roles.ViewModels
@using System.Linq
@model UserRolesViewModel
@using Orchard.Roles.ViewModels;
<fieldset>
<legend>@T("Roles")</legend>
@if (Model.Roles.Count > 0) {
var index = 0;
foreach (var entry in Model.Roles) {
if (string.Equals(entry.Name, "Authenticated", StringComparison.OrdinalIgnoreCase) || string.Equals(entry.Name, "Anonymous", StringComparison.OrdinalIgnoreCase)) {
if (SystemRoles.GetSystemRoles().Contains(entry.Name)) {
continue;
}
@Html.Hidden("Roles[" + index + "].RoleId", entry.RoleId)
@Html.Hidden("Roles[" + index + "].Name", entry.Name)
<div>
@Html.CheckBox("Roles[" + index + "].Granted", entry.Granted)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Roles[index].Granted)">@entry.Name</label>
</div>
<div>
@Html.CheckBox("Roles[" + index + "].Granted", entry.Granted)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Roles[index].Granted)">@entry.Name</label>
</div>
index++;
}
}
else {
<p>@T("There are no roles.")</p>
<p>@T("There are no roles.")</p>
}
</fieldset>

View File

@ -65,7 +65,7 @@ namespace Orchard.Rules.Providers {
}
}
public class ScheduleFormsValitator : FormHandler {
public class ScheduleFormsValidator : FormHandler {
public Localizer T { get; set; }
public override void Validating(ValidatingContext context) {

View File

@ -46,7 +46,7 @@ namespace Orchard.Workflows.Forms {
}
}
public class ScheduleFormsValitator : FormHandler {
public class ScheduleFormsValidator : FormHandler {
public Localizer T { get; set; }
public override void Validating(ValidatingContext context) {

View File

@ -1,11 +1,13 @@
using System;
using System.IO;
using Orchard.Localization;
namespace Orchard.Validation {
/// <summary>
/// Provides methods to validate paths.
/// </summary>
public static class PathValidation {
/// <summary>
/// Determines if a path lies within the base path boundaries.
/// If not, an exception is thrown.
@ -26,7 +28,7 @@ namespace Orchard.Validation {
}
if (!valid) {
throw new ArgumentException("Invalid path");
throw new OrchardException(new LocalizedString("Invalid Path"));
}
return mappedPath;