--HG--
branch : dev
This commit is contained in:
Renaud Paquay
2010-12-06 20:58:43 -08:00
17 changed files with 220 additions and 75 deletions

View File

@@ -0,0 +1,59 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>Castle.Services.Logging.Log4netIntegration</name>
</assembly>
<members>
<member name="M:Castle.Services.Logging.Log4netIntegration.ExtendedLog4netFactory.Create(System.String)">
<summary>
Creates a new extended logger.
</summary>
</member>
<member name="M:Castle.Services.Logging.Log4netIntegration.ExtendedLog4netFactory.Create(System.String,Castle.Core.Logging.LoggerLevel)">
<summary>
Creates a new extended logger.
</summary>
</member>
<member name="P:Castle.Services.Logging.Log4netIntegration.ExtendedLog4netLogger.GlobalProperties">
<summary>
Exposes the Global Context of the extended logger.
</summary>
</member>
<member name="P:Castle.Services.Logging.Log4netIntegration.ExtendedLog4netLogger.ThreadProperties">
<summary>
Exposes the Thread Context of the extended logger.
</summary>
</member>
<member name="P:Castle.Services.Logging.Log4netIntegration.ExtendedLog4netLogger.ThreadStacks">
<summary>
Exposes the Thread Stack of the extended logger.
</summary>
</member>
<member name="P:Castle.Services.Logging.Log4netIntegration.GlobalContextProperties.Item(System.String)">
<summary>
Gets or sets the value of a property
</summary>
<value>
The value for the property with the specified key
</value>
<remarks>
<para>
Gets or sets the value of a property
</para>
</remarks>
</member>
<member name="P:Castle.Services.Logging.Log4netIntegration.ThreadContextProperties.Item(System.String)">
<summary>
Gets or sets the value of a property
</summary>
<value>
The value for the property with the specified key
</value>
<remarks>
<para>
Gets or sets the value of a property
</para>
</remarks>
</member>
</members>
</doc>

View File

@@ -105,7 +105,6 @@ namespace Orchard.Specs.Bindings {
else
logger.Fatal(loggingEvent.RenderedMessage);
}
}
[Serializable]

View File

@@ -3,14 +3,35 @@ using System.Collections.Generic;
using System.Linq;
using Autofac;
using NUnit.Framework;
using Orchard.Caching;
using Orchard.Environment.Extensions.Models;
using Orchard.Roles.Models;
using Orchard.Roles.Services;
using Orchard.Security.Permissions;
using Orchard.Tests.Stubs;
namespace Orchard.Tests.Modules.Roles.Services {
[TestFixture]
public class RoleServiceTests : DatabaseEnabledTestsBase {
public override void Register(ContainerBuilder builder) {
builder.RegisterType<RoleService>().As<IRoleService>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<TestPermissionProvider>().As<IPermissionProvider>();
}
public class TestPermissionProvider : IPermissionProvider {
public Feature Feature {
get { return new Feature { Descriptor = new FeatureDescriptor { Id = "RoleServiceTests" } }; }
}
public IEnumerable<Permission> GetPermissions() {
return "alpha,beta,gamma,delta".Split(',').Select(name => new Permission { Name = name });
}
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
return Enumerable.Empty<PermissionStereotype>();
}
}
protected override IEnumerable<Type> DatabaseTypes {
@@ -34,5 +55,36 @@ namespace Orchard.Tests.Modules.Roles.Services {
Assert.That(roles, Has.Some.Property("Name").EqualTo("two"));
Assert.That(roles, Has.Some.Property("Name").EqualTo("three"));
}
[Test]
public void PermissionChangesShouldBeVisibleImmediately() {
var service = _container.Resolve<IRoleService>();
ClearSession();
{
service.CreateRole("test");
var roleId = service.GetRoleByName("test").Id;
service.UpdateRole(roleId, "test", new[] { "alpha", "beta", "gamma" });
}
ClearSession();
{
var result = service.GetPermissionsForRoleByName("test");
Assert.That(result.Count(), Is.EqualTo(3));
}
ClearSession();
{
var roleId = service.GetRoleByName("test").Id;
service.UpdateRole(roleId, "test", new[] { "alpha", "beta", "gamma", "delta" });
}
ClearSession();
{
var result = service.GetPermissionsForRoleByName("test");
Assert.That(result.Count(), Is.EqualTo(4));
}
}
}
}

View File

@@ -1,11 +1,15 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Autofac;
using log4net.Appender;
using log4net.Core;
using NUnit.Framework;
using Orchard.Environment;
using Orchard.Logging;
using Orchard.Tests.Environment;
using ILogger = Orchard.Logging.ILogger;
using ILoggerFactory = Orchard.Logging.ILoggerFactory;
using NullLogger = Orchard.Logging.NullLogger;
namespace Orchard.Tests.Logging {
[TestFixture]
@@ -51,18 +55,21 @@ namespace Orchard.Tests.Logging {
builder.RegisterType<Thing>();
builder.RegisterType<StubHostEnvironment>().As<IHostEnvironment>();
var container = builder.Build();
log4net.Config.BasicConfigurator.Configure(new MemoryAppender());
var thing = container.Resolve<Thing>();
Assert.That(thing.Logger, Is.Not.Null);
InMemoryCapture.Messages.Clear();
MemoryAppender.Messages.Clear();
thing.Logger.Error("-boom{0}-", 42);
Assert.That(InMemoryCapture.Messages, Has.Some.StringContaining("-boom42-"));
Assert.That(MemoryAppender.Messages, Has.Some.StringContaining("-boom42-"));
InMemoryCapture.Messages.Clear();
MemoryAppender.Messages.Clear();
thing.Logger.Warning(new ApplicationException("problem"), "crash");
Assert.That(InMemoryCapture.Messages, Has.Some.StringContaining("problem"));
Assert.That(InMemoryCapture.Messages, Has.Some.StringContaining("crash"));
Assert.That(InMemoryCapture.Messages, Has.Some.StringContaining("ApplicationException"));
Assert.That(MemoryAppender.Messages, Has.Some.StringContaining("problem"));
Assert.That(MemoryAppender.Messages, Has.Some.StringContaining("crash"));
Assert.That(MemoryAppender.Messages, Has.Some.StringContaining("ApplicationException"));
}
}
@@ -70,19 +77,23 @@ namespace Orchard.Tests.Logging {
public ILogger Logger { get; set; }
}
public class InMemoryCapture : TraceListener {
static InMemoryCapture() {
public class MemoryAppender : IAppender {
static MemoryAppender() {
Messages = new List<string>();
}
public static List<string> Messages { get; set; }
public override void Write(string message) {
lock (Messages) Messages.Add(message);
public void DoAppend(LoggingEvent loggingEvent) {
if (loggingEvent.ExceptionObject != null) {
lock (Messages) Messages.Add(string.Format("{0} {1} {2}",
loggingEvent.ExceptionObject.GetType().Name,
loggingEvent.ExceptionObject.Message,
loggingEvent.RenderedMessage));
} else lock (Messages) Messages.Add(loggingEvent.RenderedMessage);
}
public override void WriteLine(string message) {
lock (Messages) Messages.Add(message + System.Environment.NewLine);
}
public void Close() { }
public string Name { get; set; }
}
}

View File

@@ -90,6 +90,10 @@
<Reference Include="IronRuby.Libraries">
<HintPath>..\..\lib\dlr\IronRuby.Libraries.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\fluentnhibernate\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Dynamic, Version=1.1.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>

View File

@@ -1,27 +0,0 @@
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="Default" switchValue="Warning">
<listeners>
<add name="OrchardDebugTextLog" />
<add name="WebPageTrace"/>
</listeners>
</source>
<source name="Orchard.Localization" switchValue="Warning">
<listeners>
<add name="OrchardDebugTextLog" />
<add name="WebPageTrace"/>
</listeners>
</source>
<source name="Orchard.Data.SessionLocator" switchValue="Information">
<listeners>
<add name="OrchardDebugTextLog" />
<add name="WebPageTrace"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="OrchardDebugTextLog" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\logs\orchard-debug.txt" />
<add name="WebPageTrace" type="System.Web.WebPageTraceListener, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</sharedListeners>
</system.diagnostics>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<root>
<!-- Value of priority may be ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF -->
<priority value="INFO" />
<appender-ref ref="RollingLogFileAppender" />
</root>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="App_Data/logs/orchard-debug.txt" />
<appendToFile value="true"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger - %message%newline" />
</layout>
</appender>
</log4net>

View File

@@ -34,9 +34,6 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="HibernatingRhinos.Profiler.Appender">
<HintPath>..\..\..\..\lib\nhprof\HibernatingRhinos.Profiler.Appender.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.Data" />

View File

@@ -34,9 +34,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=2.2.4.900, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL" />
<Reference Include="HibernatingRhinos.Profiler.Appender">
<HintPath>..\..\..\..\lib\nhprof\HibernatingRhinos.Profiler.Appender.dll</HintPath>
<Reference Include="Autofac, Version=2.2.4.900, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\autofac\Autofac.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />

View File

@@ -13,5 +13,7 @@ namespace Orchard.Roles.Services {
void DeleteRole(int id);
IDictionary<string, IEnumerable<Permission>> GetInstalledPermissions();
IEnumerable<string> GetPermissionsForRole(int id);
IEnumerable<string> GetPermissionsForRoleByName(string name);
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Orchard.Caching;
using Orchard.Data;
using Orchard.Localization;
using Orchard.Logging;
@@ -11,16 +12,24 @@ using Orchard.Security.Permissions;
namespace Orchard.Roles.Services {
[UsedImplicitly]
public class RoleService : IRoleService {
private const string SignalName = "Orchard.Roles.Services.RoleService";
private readonly IRepository<RoleRecord> _roleRepository;
private readonly IRepository<PermissionRecord> _permissionRepository;
private readonly IEnumerable<IPermissionProvider> _permissionProviders;
private readonly ICacheManager _cacheManager;
private readonly ISignals _signals;
public RoleService(IRepository<RoleRecord> roleRepository,
IRepository<PermissionRecord> permissionRepository,
IEnumerable<IPermissionProvider> permissionProviders) {
IEnumerable<IPermissionProvider> permissionProviders,
ICacheManager cacheManager,
ISignals signals) {
_roleRepository = roleRepository;
_permissionRepository = permissionRepository;
_permissionProviders = permissionProviders;
_cacheManager = cacheManager;
_signals = signals;
Logger = NullLogger.Instance;
T = NullLocalizer.Instance;
}
@@ -43,6 +52,7 @@ namespace Orchard.Roles.Services {
public void CreateRole(string roleName) {
_roleRepository.Create(new RoleRecord { Name = roleName });
TriggerSignal();
}
public void CreatePermissionForRole(string roleName, string permissionName) {
@@ -56,6 +66,7 @@ namespace Orchard.Roles.Services {
RoleRecord roleRecord = GetRoleByName(roleName);
PermissionRecord permissionRecord = _permissionRepository.Get(x => x.Name == permissionName);
roleRecord.RolesPermissions.Add(new RolesPermissionsRecord { Permission = permissionRecord, Role = roleRecord });
TriggerSignal();
}
public void UpdateRole(int id, string roleName, IEnumerable<string> rolePermissions) {
@@ -73,6 +84,7 @@ namespace Orchard.Roles.Services {
}
PermissionRecord permissionRecord = _permissionRepository.Get(x => x.Name == permission);
roleRecord.RolesPermissions.Add(new RolesPermissionsRecord { Permission = permissionRecord, Role = roleRecord });
TriggerSignal();
}
}
@@ -100,6 +112,7 @@ namespace Orchard.Roles.Services {
public void DeleteRole(int id) {
_roleRepository.Delete(GetRole(id));
TriggerSignal();
}
public IDictionary<string, IEnumerable<Permission>> GetInstalledPermissions() {
@@ -130,5 +143,28 @@ namespace Orchard.Roles.Services {
}
return permissions;
}
public IEnumerable<string> GetPermissionsForRoleByName(string name) {
return _cacheManager.Get(name, ctx => {
MonitorSignal(ctx);
return GetPermissionsForRoleByNameInner(name);
});
}
IEnumerable<string> GetPermissionsForRoleByNameInner(string name) {
var roleRecord = GetRoleByName(name);
if (roleRecord == null)
return Enumerable.Empty<string>();
return GetPermissionsForRole(roleRecord.Id);
}
private void MonitorSignal(AcquireContext<string> ctx) {
ctx.Monitor(_signals.When(SignalName));
}
private void TriggerSignal() {
_signals.Trigger(SignalName);
}
}
}

View File

@@ -71,10 +71,7 @@ namespace Orchard.Roles.Services {
}
foreach (var role in rolesToExamine) {
RoleRecord roleRecord = _roleService.GetRoleByName(role);
if ( roleRecord == null )
continue;
foreach (var permissionName in _roleService.GetPermissionsForRole(roleRecord.Id)) {
foreach (var permissionName in _roleService.GetPermissionsForRoleByName(role)) {
string possessedName = permissionName;
if (grantingNames.Any(grantingName => String.Equals(possessedName, grantingName, StringComparison.OrdinalIgnoreCase))) {
context.Granted = true;

View File

@@ -125,6 +125,7 @@
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Content Include="Config\log4net.config" />
<None Include="Media\web.config" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
@@ -151,11 +152,6 @@
<Name>Orchard.Core</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Config\Diagnostics.config">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Config\Sample.Host.config" />
</ItemGroup>

View File

@@ -13,9 +13,14 @@
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor" requirePermission="false" />
</sectionGroup>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
</configSections>
<system.diagnostics configSource="Config\Diagnostics.config"/>
<appSettings>
<add key="webpages:Enabled" value="false" />
<add key="log4net.Config" value="Config\log4net.config" />
</appSettings>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

View File

@@ -5,8 +5,7 @@ using System.Linq;
using System.Reflection;
using Autofac;
using Autofac.Core;
using Castle.Core.Logging;
using Orchard.Environment;
using Castle.Services.Logging.Log4netIntegration;
using Module = Autofac.Module;
namespace Orchard.Logging {
@@ -21,16 +20,7 @@ namespace Orchard.Logging {
protected override void Load(ContainerBuilder moduleBuilder) {
// by default, use Orchard's logger that delegates to Castle's logger factory
moduleBuilder.RegisterType<CastleLoggerFactory>().As<ILoggerFactory>().InstancePerLifetimeScope();
moduleBuilder.Register<Castle.Core.Logging.ILoggerFactory>(componentContext => {
IHostEnvironment host = componentContext.Resolve<IHostEnvironment>();
if (host.IsFullTrust)
return new TraceLoggerFactory();
return new NullLogFactory();
})
.As<Castle.Core.Logging.ILoggerFactory>()
.InstancePerLifetimeScope();
moduleBuilder.RegisterType<Log4netFactory>().As<Castle.Core.Logging.ILoggerFactory>().InstancePerLifetimeScope();
// call CreateLogger in response to the request for an ILogger implementation
moduleBuilder.Register(CreateLogger).As<ILogger>().InstancePerDependency();

View File

@@ -77,6 +77,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\Castle Windsor 2.0\bin\Castle.DynamicProxy2.dll</HintPath>
</Reference>
<Reference Include="Castle.Services.Logging.Log4netIntegration">
<HintPath>..\..\lib\Castle Windsor 2.0\bin\Castle.Services.Logging.Log4netIntegration.dll</HintPath>
</Reference>
<Reference Include="ClaySharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\claysharp\ClaySharp.dll</HintPath>
@@ -89,6 +92,10 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\sharpziplib\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\fluentnhibernate\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Web.Infrastructure">
<HintPath>..\..\lib\aspnetmvc\Microsoft.Web.Infrastructure.dll</HintPath>