Skip to content
This repository has been archived by the owner on Sep 18, 2021. It is now read-only.

add localization service #661

Merged
merged 2 commits into from
Dec 21, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions source/Core/Configuration/Hosting/AutoFacConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,15 @@ public static IContainer Configure(IdentityServerOptions options)
{
builder.RegisterType<DefaultRedirectUriValidator>().As<IRedirectUriValidator>();
}

if (fact.LocalizationService != null)
{
builder.Register(fact.LocalizationService);
}
else
{
builder.RegisterType<DefaultLocalizationService>().As<ILocalizationService>();
}

// this is more of an internal interface, but maybe we want to open it up as pluggable?
// this is used by the DefaultClientPermissionsService below, or it could be used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System.Web.Http.Filters;
using Thinktecture.IdentityServer.Core.Extensions;
using Thinktecture.IdentityServer.Core.Logging;
using Thinktecture.IdentityServer.Core.Resources;
using Thinktecture.IdentityServer.Core.Results;
using Thinktecture.IdentityServer.Core.Services;
using Thinktecture.IdentityServer.Core.ViewModels;
Expand All @@ -35,11 +36,12 @@ public override async System.Threading.Tasks.Task OnExceptionAsync(HttpActionExe
var env = actionExecutedContext.ActionContext.Request.GetOwinEnvironment();
var options = env.ResolveDependency<IdentityServerOptions>();
var viewSvc = env.ResolveDependency<IViewService>();
var localization = env.ResolveDependency<ILocalizationService>();
var errorModel = new ErrorViewModel
{
SiteName = options.SiteName,
SiteUrl = env.GetIdentityServerBaseUrl(),
ErrorMessage = Resources.Messages.UnexpectedError,
ErrorMessage = localization.GetMessage(MessageIds.UnexpectedError),
};
var errorResult = new ErrorActionResult(viewSvc, errorModel);
actionExecutedContext.Response = await errorResult.GetResponseMessage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Thinktecture.IdentityServer.Core.Resources;
using Thinktecture.IdentityServer.Core.Services;
using Thinktecture.IdentityServer.Core.Extensions;

namespace Thinktecture.IdentityServer.Core.Configuration.Hosting
{
Expand Down Expand Up @@ -50,7 +52,13 @@ public override void OnAuthorization(HttpActionContext actionContext)
return;
}

actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType, new { ErrorMessage = Messages.UnsupportedMediaType });
var env = actionContext.Request.GetOwinEnvironment();
var localization = env.ResolveDependency<ILocalizationService>();

actionContext.Response = actionContext.Request.CreateResponse(
HttpStatusCode.UnsupportedMediaType,
new { ErrorMessage = localization.GetMessage(MessageIds.UnsupportedMediaType) }
);
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions source/Core/Configuration/Hosting/RequireSslMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Thinktecture.IdentityServer.Core.Resources;
using Thinktecture.IdentityServer.Core.Extensions;
using Thinktecture.IdentityServer.Core.Services;

namespace Thinktecture.IdentityServer.Core.Configuration.Hosting
{
Expand All @@ -36,10 +38,12 @@ public async Task Invoke(IDictionary<string, object> env)

if (context.Request.Uri.Scheme != Uri.UriSchemeHttps)
{
var localization = env.ResolveDependency<ILocalizationService>();

context.Response.StatusCode = 403;
context.Response.ReasonPhrase = Messages.SslRequired;
context.Response.ReasonPhrase = localization.GetMessage(MessageIds.SslRequired);

await context.Response.WriteAsync(Messages.SslRequired);
await context.Response.WriteAsync(context.Response.ReasonPhrase);

return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,13 @@ private static async Task ValidateTokens(HttpActionContext actionContext)

var options = env.ResolveDependency<IdentityServerOptions>();
var viewSvc = env.ResolveDependency<IViewService>();
var localization = env.ResolveDependency<ILocalizationService>();

var errorModel = new ErrorViewModel
{
SiteName = options.SiteName,
SiteUrl = env.GetIdentityServerBaseUrl(),
ErrorMessage = Resources.Messages.UnexpectedError,
ErrorMessage = localization.GetMessage(Resources.MessageIds.UnexpectedError),
};
var errorResult = new ErrorActionResult(viewSvc, errorModel);
actionContext.Response = await errorResult.GetResponseMessage();
Expand Down
8 changes: 8 additions & 0 deletions source/Core/Configuration/IdentityServerServiceFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,14 @@ public void Register<T>(Registration<T> registration)
/// The redirect URI validator.
/// </value>
public Registration<IRedirectUriValidator> RedirectUriValidator { get; set; }

/// <summary>
/// Gets or sets the localization service.
/// </summary>
/// <value>
/// The localization service.
/// </value>
public Registration<ILocalizationService> LocalizationService { get; set; }

internal void Validate()
{
Expand Down
12 changes: 12 additions & 0 deletions source/Core/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ public static class Constants

public const string DefaultHashAlgorithm = "SHA256";

public const string ScopeDisplayNameSuffix = "_DisplayName";
public const string ScopeDescriptionSuffix = "_Description";

public static class AuthorizeRequest
{
public const string Scope = "scope";
Expand Down Expand Up @@ -526,5 +529,14 @@ public static class Authentication
public const string SigninId = "signinid";
public const string KatanaAuthenticationType = "katanaAuthenticationType";
}

public static class LocalizationCategories
{
public const string Messages = "Messages";
public const string Events = "Events";
public const string Scopes = "Scopes";
}


}
}
17 changes: 16 additions & 1 deletion source/Core/Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,21 @@
<Compile Include="Events\AuthenticationEvent.cs" />
<Compile Include="Events\ExternalAuthenticationEvent.cs" />
<Compile Include="Extensions\IEventServiceExtensions.cs" />
<Compile Include="Extensions\ILocalizationServiceExtensions.cs" />
<Compile Include="Logging\ActivityId.cs" />
<Compile Include="Logging\LibLogTraceListener.cs" />
<Compile Include="Models\ScopeString.cs" />
<Compile Include="Models\Message.cs" />
<Compile Include="Resources\T4resx.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>T4resx.tt</DependentUpon>
</Compile>
<Compile Include="Services\Default\AutofacDependencyResolver.cs" />
<Compile Include="Services\Default\DefaultLocalizationService.cs" />
<Compile Include="Services\Default\DefaultRedirectUriValidator.cs" />
<Compile Include="Services\IDependencyResolver.cs" />
<Compile Include="Services\ILocalizationService.cs" />
<Compile Include="Services\IRedirectUriValidator.cs" />
<Compile Include="Services\OwinEnvironmentService.cs" />
<Compile Include="Validation\BearerTokenUsageType.cs" />
Expand Down Expand Up @@ -356,7 +365,9 @@
<Compile Include="Services\IViewService.cs" />
<Compile Include="ViewModels\ClientPermissionsViewModel.cs" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Events.resx">
<Generator>ResXFileCodeGenerator</Generator>
Expand All @@ -370,6 +381,10 @@
<Link>default.licenseheader</Link>
</None>
<None Include="app.config" />
<None Include="Resources\T4resx.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>T4resx.cs</LastGenOutput>
</None>
<None Include="Services\DefaultViewService\HttpAssets\app\app.less" />
<None Include="Services\DefaultViewService\HttpAssets\libs\bootstrap\custom.less" />
<EmbeddedResource Include="Resources\Scopes.resx">
Expand Down
50 changes: 32 additions & 18 deletions source/Core/Endpoints/AuthenticationController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,24 @@ public class AuthenticationController : ApiController
private readonly IdentityServerOptions _options;
private readonly IClientStore _clientStore;
private readonly IEventService _events;
private readonly ILocalizationService _localizationService;

public AuthenticationController(
IViewService viewService,
IUserService userService,
AuthenticationOptions authenticationOptions,
IdentityServerOptions idSvrOptions,
IClientStore clientStore,
IEventService events)
IEventService events,
ILocalizationService localizationService)
{
_viewService = viewService;
_userService = userService;
_authenticationOptions = authenticationOptions;
_options = idSvrOptions;
_clientStore = clientStore;
_events = events;
_localizationService = localizationService;
}

[Route(Constants.RoutePaths.Login, Name = Constants.RouteNames.Login)]
Expand All @@ -77,15 +80,16 @@ public async Task<IHttpActionResult> Login(string signin)
if (signin.IsMissing())
{
Logger.Error("No signin id passed");
return RenderErrorPage(Messages.NoSignInCookie);
return RenderErrorPage(_localizationService.GetMessage(MessageIds.NoSignInCookie));
}

var cookie = new MessageCookie<SignInMessage>(Request.GetOwinContext(), this._options);
var signInMessage = cookie.Read(signin);
if (signInMessage == null)
{
Logger.Error("No cookie matching signin id found");
return RenderErrorPage(Messages.NoSignInCookie);
return RenderErrorPage(
_localizationService.GetMessage(MessageIds.NoSignInCookie));
}

Logger.DebugFormat("signin message passed to login: {0}", JsonConvert.SerializeObject(signInMessage, Formatting.Indented));
Expand Down Expand Up @@ -128,21 +132,31 @@ public async Task<IHttpActionResult> LoginLocal(string signin, LoginCredentials
if (signin.IsMissing())
{
Logger.Error("No signin id passed");
return RenderErrorPage(Messages.NoSignInCookie);
return RenderErrorPage(_localizationService.GetMessage(MessageIds.NoSignInCookie));
}

var cookie = new MessageCookie<SignInMessage>(Request.GetOwinContext(), this._options);
var signInMessage = cookie.Read(signin);
if (signInMessage == null)
{
Logger.Error("No cookie matching signin id found");
return RenderErrorPage(Messages.NoSignInCookie);
return RenderErrorPage(_localizationService.GetMessage(MessageIds.NoSignInCookie));
}

if (model == null)
{
Logger.Error("no data submitted");
return await RenderLoginPage(signInMessage, signin, Messages.InvalidUsernameOrPassword);
return await RenderLoginPage(signInMessage, signin, _localizationService.GetMessage(MessageIds.InvalidUsernameOrPassword));
}

if (String.IsNullOrWhiteSpace(model.Username))
{
ModelState.AddModelError("Username", _localizationService.GetMessage(MessageIds.UsernameRequired));
}

if (String.IsNullOrWhiteSpace(model.Password))
{
ModelState.AddModelError("Password", _localizationService.GetMessage(MessageIds.PasswordRequired));
}

// the browser will only send 'true' if ther user has checked the checkbox
Expand Down Expand Up @@ -172,7 +186,7 @@ public async Task<IHttpActionResult> LoginLocal(string signin, LoginCredentials
if (authResult == null)
{
Logger.WarnFormat("user service indicated incorrect username or password for username: {0}", model.Username);
return await RenderLoginPage(signInMessage, signin, Messages.InvalidUsernameOrPassword, model.Username, model.RememberMe == true);
return await RenderLoginPage(signInMessage, signin, _localizationService.GetMessage(MessageIds.InvalidUsernameOrPassword), model.Username, model.RememberMe == true);
}

if (authResult.IsError)
Expand All @@ -197,21 +211,21 @@ public async Task<IHttpActionResult> LoginExternal(string signin, string provide
if (provider.IsMissing())
{
Logger.Error("No provider passed");
return RenderErrorPage(Messages.NoExternalProvider);
return RenderErrorPage(_localizationService.GetMessage(MessageIds.NoExternalProvider));
}

if (signin.IsMissing())
{
Logger.Error("No signin id passed");
return RenderErrorPage(Messages.NoSignInCookie);
return RenderErrorPage(_localizationService.GetMessage(MessageIds.NoSignInCookie));
}

var cookie = new MessageCookie<SignInMessage>(Request.GetOwinContext(), this._options);
var signInMessage = cookie.Read(signin);
if (signInMessage == null)
{
Logger.Error("No cookie matching signin id found");
return RenderErrorPage(Messages.NoSignInCookie);
return RenderErrorPage(_localizationService.GetMessage(MessageIds.NoSignInCookie));
}

var providerFilter = await GetProviderFilterForClientAsync(signInMessage);
Expand Down Expand Up @@ -244,29 +258,29 @@ public async Task<IHttpActionResult> LoginExternalCallback()
if (signInId.IsMissing())
{
Logger.Error("No signin id passed");
return RenderErrorPage(Messages.NoSignInCookie);
return RenderErrorPage(_localizationService.GetMessage(MessageIds.NoSignInCookie));
}

var cookie = new MessageCookie<SignInMessage>(Request.GetOwinContext(), this._options);
var signInMessage = cookie.Read(signInId);
if (signInMessage == null)
{
Logger.Error("No cookie matching signin id found");
return RenderErrorPage(Messages.NoSignInCookie);
return RenderErrorPage(_localizationService.GetMessage(MessageIds.NoSignInCookie));
}

var user = await GetIdentityFromExternalProvider();
if (user == null)
{
Logger.Error("no identity from external identity provider");
return await RenderLoginPage(signInMessage, signInId, Messages.NoMatchingExternalAccount);
return await RenderLoginPage(signInMessage, signInId, _localizationService.GetMessage(MessageIds.NoMatchingExternalAccount));
}

var externalIdentity = ExternalIdentity.FromClaims(user.Claims);
if (externalIdentity == null)
{
Logger.Error("no subject or unique identifier claims from external identity provider");
return await RenderLoginPage(signInMessage, signInId, Messages.NoMatchingExternalAccount);
return await RenderLoginPage(signInMessage, signInId, _localizationService.GetMessage(MessageIds.NoMatchingExternalAccount));
}

Logger.InfoFormat("external user provider: {0}, provider ID: {1}", externalIdentity.Provider, externalIdentity.ProviderId);
Expand All @@ -275,7 +289,7 @@ public async Task<IHttpActionResult> LoginExternalCallback()
if (authResult == null)
{
Logger.Warn("user service failed to authenticate external identity");
return await RenderLoginPage(signInMessage, signInId, Messages.NoMatchingExternalAccount);
return await RenderLoginPage(signInMessage, signInId, _localizationService.GetMessage(MessageIds.NoMatchingExternalAccount));
}

if (authResult.IsError)
Expand Down Expand Up @@ -326,7 +340,7 @@ public async Task<IHttpActionResult> ResumeLoginFromRedirect(string resume)
if (signInMessage == null)
{
Logger.Error("No cookie matching signin id found");
return RenderErrorPage(Messages.NoSignInCookie);
return RenderErrorPage(_localizationService.GetMessage(MessageIds.NoSignInCookie));
}

AuthenticateResult result = null;
Expand Down Expand Up @@ -356,7 +370,7 @@ public async Task<IHttpActionResult> ResumeLoginFromRedirect(string resume)
if (result == null)
{
Logger.Warn("user service failed to authenticate external identity");
return await RenderLoginPage(signInMessage, signInId, Messages.NoMatchingExternalAccount);
return await RenderLoginPage(signInMessage, signInId, _localizationService.GetMessage(MessageIds.NoMatchingExternalAccount));
}

if (result.IsError)
Expand Down Expand Up @@ -801,7 +815,7 @@ private async Task<string> GetClientNameFromSignOutMessage(SignOutMessage signOu

private IHttpActionResult RenderErrorPage(string message = null)
{
message = message ?? Messages.UnexpectedError;
message = message ?? _localizationService.GetMessage(MessageIds.UnexpectedError);
var errorModel = new ErrorViewModel
{
SiteName = this._options.SiteName,
Expand Down
Loading