2020-05-20 16:43:06 +10:00
using System.Runtime.Serialization ;
2020-08-20 22:18:50 +01:00
using Microsoft.AspNetCore.Http ;
2022-08-16 10:10:51 +02:00
using Microsoft.AspNetCore.Mvc.ViewFeatures ;
2020-08-20 22:18:50 +01:00
using Microsoft.AspNetCore.Routing ;
2022-05-24 09:01:32 +02:00
using Microsoft.Extensions.DependencyInjection ;
2020-08-20 22:18:50 +01:00
using Microsoft.Extensions.Options ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core ;
using Umbraco.Cms.Core.Configuration ;
using Umbraco.Cms.Core.Configuration.Models ;
using Umbraco.Cms.Core.Features ;
using Umbraco.Cms.Core.Hosting ;
2021-02-25 15:08:56 +01:00
using Umbraco.Cms.Core.Mail ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.Media ;
2022-03-30 15:58:46 +02:00
using Umbraco.Cms.Core.Models ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.Models.ContentEditing ;
2022-03-30 15:58:46 +02:00
using Umbraco.Cms.Core.Models.TemplateQuery ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.Services ;
using Umbraco.Cms.Core.Trees ;
using Umbraco.Cms.Core.WebAssets ;
2021-02-10 11:11:18 +01:00
using Umbraco.Cms.Web.BackOffice.HealthChecks ;
using Umbraco.Cms.Web.BackOffice.Profiling ;
using Umbraco.Cms.Web.BackOffice.PropertyEditors ;
using Umbraco.Cms.Web.BackOffice.Routing ;
using Umbraco.Cms.Web.BackOffice.Security ;
using Umbraco.Cms.Web.BackOffice.Trees ;
2021-02-10 11:42:04 +01:00
using Umbraco.Cms.Web.Common.Attributes ;
2022-05-24 09:01:32 +02:00
using Umbraco.Cms.Web.Common.DependencyInjection ;
2022-03-30 15:58:46 +02:00
using Umbraco.Cms.Web.Common.Models ;
2020-05-20 16:43:06 +10:00
using Umbraco.Extensions ;
2021-02-10 11:11:18 +01:00
namespace Umbraco.Cms.Web.BackOffice.Controllers
2020-05-20 16:43:06 +10:00
{
/// <summary>
/// Used to collect the server variables for use in the back office angular app
/// </summary>
public class BackOfficeServerVariables
{
private readonly LinkGenerator _linkGenerator ;
private readonly IRuntimeState _runtimeState ;
private readonly UmbracoFeatures _features ;
2022-05-24 09:01:32 +02:00
private GlobalSettings _globalSettings ;
2020-05-20 16:43:06 +10:00
private readonly IUmbracoVersion _umbracoVersion ;
2022-05-24 09:01:32 +02:00
private ContentSettings _contentSettings ;
2020-06-09 07:49:26 +02:00
private readonly TreeCollection _treeCollection ;
2020-05-20 16:43:06 +10:00
private readonly IHttpContextAccessor _httpContextAccessor ;
private readonly IHostingEnvironment _hostingEnvironment ;
2022-05-24 09:01:32 +02:00
private RuntimeSettings _runtimeSettings ;
private SecuritySettings _securitySettings ;
2020-05-20 16:43:06 +10:00
private readonly IRuntimeMinifier _runtimeMinifier ;
2020-10-23 14:18:53 +11:00
private readonly IBackOfficeExternalLoginProviders _externalLogins ;
2020-09-22 15:06:03 +02:00
private readonly IImageUrlGenerator _imageUrlGenerator ;
2020-10-01 07:03:31 +02:00
private readonly PreviewRoutes _previewRoutes ;
2021-02-25 15:08:56 +01:00
private readonly IEmailSender _emailSender ;
2021-09-23 10:38:53 +02:00
private MemberPasswordConfigurationSettings _memberPasswordConfigurationSettings ;
2022-05-24 09:01:32 +02:00
private DataTypesSettings _dataTypesSettings ;
2022-08-16 10:10:51 +02:00
private readonly ITempDataDictionaryFactory _tempDataDictionaryFactory ;
2020-05-20 16:43:06 +10:00
2022-05-24 09:01:32 +02:00
[Obsolete("Use constructor that takes IOptionsMontior<DataTypeSettings>, scheduled for removal in V12")]
2020-05-20 16:43:06 +10:00
public BackOfficeServerVariables (
LinkGenerator linkGenerator ,
IRuntimeState runtimeState ,
UmbracoFeatures features ,
2021-09-23 10:30:22 +02:00
IOptionsMonitor < GlobalSettings > globalSettings ,
2020-05-20 16:43:06 +10:00
IUmbracoVersion umbracoVersion ,
2021-09-23 10:30:22 +02:00
IOptionsMonitor < ContentSettings > contentSettings ,
2020-05-25 19:37:16 +10:00
IHttpContextAccessor httpContextAccessor ,
2020-06-09 07:49:26 +02:00
TreeCollection treeCollection ,
2020-05-20 16:43:06 +10:00
IHostingEnvironment hostingEnvironment ,
2021-09-23 10:30:22 +02:00
IOptionsMonitor < RuntimeSettings > runtimeSettings ,
IOptionsMonitor < SecuritySettings > securitySettings ,
2020-05-20 16:43:06 +10:00
IRuntimeMinifier runtimeMinifier ,
2020-10-23 14:18:53 +11:00
IBackOfficeExternalLoginProviders externalLogins ,
2020-09-30 10:02:28 +02:00
IImageUrlGenerator imageUrlGenerator ,
2021-02-25 15:08:56 +01:00
PreviewRoutes previewRoutes ,
2021-04-20 19:34:18 +02:00
IEmailSender emailSender ,
2021-09-23 10:38:53 +02:00
IOptionsMonitor < MemberPasswordConfigurationSettings > memberPasswordConfigurationSettings )
2022-05-24 09:01:32 +02:00
: this (
linkGenerator ,
runtimeState ,
features ,
globalSettings ,
umbracoVersion ,
contentSettings ,
httpContextAccessor ,
treeCollection ,
hostingEnvironment ,
runtimeSettings ,
securitySettings ,
runtimeMinifier ,
externalLogins ,
imageUrlGenerator ,
previewRoutes ,
emailSender ,
memberPasswordConfigurationSettings ,
StaticServiceProvider . Instance . GetRequiredService < IOptionsMonitor < DataTypesSettings > > ( ) )
{
}
2022-08-16 10:10:51 +02:00
[Obsolete("Use constructor that takes ITempDataDictionaryFactory, scheduled for removal in V12")]
2022-05-24 09:01:32 +02:00
public BackOfficeServerVariables (
LinkGenerator linkGenerator ,
IRuntimeState runtimeState ,
UmbracoFeatures features ,
IOptionsMonitor < GlobalSettings > globalSettings ,
IUmbracoVersion umbracoVersion ,
IOptionsMonitor < ContentSettings > contentSettings ,
IHttpContextAccessor httpContextAccessor ,
TreeCollection treeCollection ,
IHostingEnvironment hostingEnvironment ,
IOptionsMonitor < RuntimeSettings > runtimeSettings ,
IOptionsMonitor < SecuritySettings > securitySettings ,
IRuntimeMinifier runtimeMinifier ,
IBackOfficeExternalLoginProviders externalLogins ,
IImageUrlGenerator imageUrlGenerator ,
PreviewRoutes previewRoutes ,
IEmailSender emailSender ,
IOptionsMonitor < MemberPasswordConfigurationSettings > memberPasswordConfigurationSettings ,
IOptionsMonitor < DataTypesSettings > dataTypesSettings )
2022-08-16 10:10:51 +02:00
: this (
linkGenerator ,
runtimeState ,
features ,
globalSettings ,
umbracoVersion ,
contentSettings ,
httpContextAccessor ,
treeCollection ,
hostingEnvironment ,
runtimeSettings ,
securitySettings ,
runtimeMinifier ,
externalLogins ,
imageUrlGenerator ,
previewRoutes ,
emailSender ,
memberPasswordConfigurationSettings ,
dataTypesSettings ,
StaticServiceProvider . Instance . GetRequiredService < ITempDataDictionaryFactory > ( ) )
{
}
public BackOfficeServerVariables (
LinkGenerator linkGenerator ,
IRuntimeState runtimeState ,
UmbracoFeatures features ,
IOptionsMonitor < GlobalSettings > globalSettings ,
IUmbracoVersion umbracoVersion ,
IOptionsMonitor < ContentSettings > contentSettings ,
IHttpContextAccessor httpContextAccessor ,
TreeCollection treeCollection ,
IHostingEnvironment hostingEnvironment ,
IOptionsMonitor < RuntimeSettings > runtimeSettings ,
IOptionsMonitor < SecuritySettings > securitySettings ,
IRuntimeMinifier runtimeMinifier ,
IBackOfficeExternalLoginProviders externalLogins ,
IImageUrlGenerator imageUrlGenerator ,
PreviewRoutes previewRoutes ,
IEmailSender emailSender ,
IOptionsMonitor < MemberPasswordConfigurationSettings > memberPasswordConfigurationSettings ,
IOptionsMonitor < DataTypesSettings > dataTypesSettings ,
ITempDataDictionaryFactory tempDataDictionaryFactory )
2020-05-20 16:43:06 +10:00
{
_linkGenerator = linkGenerator ;
_runtimeState = runtimeState ;
_features = features ;
2021-09-23 10:30:22 +02:00
_globalSettings = globalSettings . CurrentValue ;
2020-05-20 16:43:06 +10:00
_umbracoVersion = umbracoVersion ;
2021-09-23 10:30:22 +02:00
_contentSettings = contentSettings . CurrentValue ? ? throw new ArgumentNullException ( nameof ( contentSettings ) ) ;
2020-05-25 19:37:16 +10:00
_httpContextAccessor = httpContextAccessor ;
2020-06-09 07:49:26 +02:00
_treeCollection = treeCollection ? ? throw new ArgumentNullException ( nameof ( treeCollection ) ) ;
2020-05-20 16:43:06 +10:00
_hostingEnvironment = hostingEnvironment ;
2021-09-23 10:30:22 +02:00
_runtimeSettings = runtimeSettings . CurrentValue ;
_securitySettings = securitySettings . CurrentValue ;
2020-05-20 16:43:06 +10:00
_runtimeMinifier = runtimeMinifier ;
2020-10-23 14:18:53 +11:00
_externalLogins = externalLogins ;
2020-09-22 15:06:03 +02:00
_imageUrlGenerator = imageUrlGenerator ;
2020-10-01 07:03:31 +02:00
_previewRoutes = previewRoutes ;
2021-02-25 15:08:56 +01:00
_emailSender = emailSender ;
2022-08-16 10:10:51 +02:00
_tempDataDictionaryFactory = tempDataDictionaryFactory ;
2021-09-23 10:38:53 +02:00
_memberPasswordConfigurationSettings = memberPasswordConfigurationSettings . CurrentValue ;
2022-05-24 09:01:32 +02:00
_dataTypesSettings = dataTypesSettings . CurrentValue ;
2021-09-23 10:30:22 +02:00
globalSettings . OnChange ( x = > _globalSettings = x ) ;
contentSettings . OnChange ( x = > _contentSettings = x ) ;
runtimeSettings . OnChange ( x = > _runtimeSettings = x ) ;
securitySettings . OnChange ( x = > _securitySettings = x ) ;
2022-05-24 09:01:32 +02:00
dataTypesSettings . OnChange ( x = > _dataTypesSettings = x ) ;
2021-09-23 10:38:53 +02:00
memberPasswordConfigurationSettings . OnChange ( x = > _memberPasswordConfigurationSettings = x ) ;
2020-05-20 16:43:06 +10:00
}
/// <summary>
/// Returns the server variables for non-authenticated users
/// </summary>
/// <returns></returns>
internal async Task < Dictionary < string , object > > BareMinimumServerVariablesAsync ( )
{
2022-08-16 10:10:51 +02:00
// figure out if we are executing in context of a backoffice user
HttpContext ? context = _httpContextAccessor . HttpContext ;
var isBackofficeUser = false ;
if ( context ! = null )
{
// first look for an authorized user (this covers both logged in and invited users)
isBackofficeUser = ( await context . AuthenticateBackOfficeAsync ( ) ) . Succeeded ;
if ( isBackofficeUser = = false )
{
// here's where things get a little ugly:
// when a backoffice user is about to reset their password, TempData[ViewDataExtensions.TokenPasswordResetCode]
// contains a JSON object with the current user ID and a password reset code - see ValidatePasswordResetCodeModel
ITempDataDictionary tempData = _tempDataDictionaryFactory . GetTempData ( context ) ;
var passwordResetCode = tempData [ ViewDataExtensions . TokenPasswordResetCode ] ;
isBackofficeUser = passwordResetCode is string passwordResetCodeString & & passwordResetCodeString . InvariantContains ( "userId" ) ;
}
}
2020-05-20 16:43:06 +10:00
//this is the filter for the keys that we'll keep based on the full version of the server vars
2022-08-16 10:10:51 +02:00
var umbracoSettings = new List < string > {
"allowPasswordReset" ,
"imageFileTypes" ,
"loginBackgroundImage" ,
"loginLogoImage" ,
"canSendRequiredEmail" ,
"usernameIsEmail" ,
"hideBackofficeLogo" ,
"disableDeleteWhenReferenced" ,
"disableUnpublishWhenReferenced"
} ;
// add a few extras for backoffice users (server vars we don't want floating around for anonymous users)
if ( isBackofficeUser )
{
umbracoSettings . AddRange ( new [ ] { "maxFileSize" , "minimumPasswordLength" , "minimumPasswordNonAlphaNum" } ) ;
}
2020-05-20 16:43:06 +10:00
var keepOnlyKeys = new Dictionary < string , string [ ] >
{
2021-03-19 16:17:39 +01:00
{ "umbracoUrls" , new [ ] { "authenticationApiBaseUrl" , "serverVarsJs" , "externalLoginsUrl" , "currentUserApiBaseUrl" , "previewHubUrl" , "iconApiBaseUrl" } } ,
2022-08-16 10:10:51 +02:00
{ "umbracoSettings" , umbracoSettings . ToArray ( ) } ,
2020-05-20 16:43:06 +10:00
{ "application" , new [ ] { "applicationPath" , "cacheBuster" } } ,
{ "isDebuggingEnabled" , new string [ ] { } } ,
{ "features" , new [ ] { "disabledFeatures" } }
} ;
2022-08-16 10:10:51 +02:00
2020-05-20 16:43:06 +10:00
//now do the filtering...
2022-06-20 08:37:17 +02:00
Dictionary < string , object > defaults = await GetServerVariablesAsync ( ) ;
2020-05-20 16:43:06 +10:00
foreach ( var key in defaults . Keys . ToArray ( ) )
{
if ( keepOnlyKeys . ContainsKey ( key ) = = false )
{
defaults . Remove ( key ) ;
}
else
{
if ( defaults [ key ] is System . Collections . IDictionary asDictionary )
{
var toKeep = keepOnlyKeys [ key ] ;
foreach ( var k in asDictionary . Keys . Cast < string > ( ) . ToArray ( ) )
{
if ( toKeep . Contains ( k ) = = false )
{
asDictionary . Remove ( k ) ;
}
}
}
}
}
// TODO: This is ultra confusing! this same key is used for different things, when returning the full app when authenticated it is this URL but when not auth'd it's actually the ServerVariables address
// so based on compat and how things are currently working we need to replace the serverVarsJs one
2022-03-30 15:58:46 +02:00
( ( Dictionary < string , object? > ) defaults [ "umbracoUrls" ] ) [ "serverVarsJs" ]
2020-05-25 23:15:32 +10:00
= _linkGenerator . GetPathByAction (
nameof ( BackOfficeController . ServerVariables ) ,
ControllerExtensions . GetControllerName < BackOfficeController > ( ) ,
new { area = Constants . Web . Mvc . BackOfficeArea } ) ;
2020-05-20 16:43:06 +10:00
return defaults ;
}
/// <summary>
/// Returns the server variables for authenticated users
/// </summary>
/// <returns></returns>
2021-07-27 16:12:23 -06:00
internal async Task < Dictionary < string , object > > GetServerVariablesAsync ( )
2020-05-20 16:43:06 +10:00
{
2022-06-20 08:37:17 +02:00
GlobalSettings globalSettings = _globalSettings ;
2020-05-25 23:15:32 +10:00
var backOfficeControllerName = ControllerExtensions . GetControllerName < BackOfficeController > ( ) ;
2020-05-20 16:43:06 +10:00
var defaultVals = new Dictionary < string , object >
{
{
2022-03-30 15:58:46 +02:00
"umbracoUrls" , new Dictionary < string , object? >
2020-05-20 16:43:06 +10:00
{
// TODO: Add 'umbracoApiControllerBaseUrl' which people can use in JS
// to prepend their URL. We could then also use this in our own resources instead of
2020-10-05 20:48:38 +02:00
// having each URL defined here explicitly - we can do that in v8! for now
2020-05-20 16:43:06 +10:00
// for umbraco services we'll stick to explicitly defining the endpoints.
2020-11-27 13:34:32 +01:00
{ "externalLoginsUrl" , _linkGenerator . GetPathByAction ( nameof ( BackOfficeController . ExternalLogin ) , backOfficeControllerName , new { area = Constants . Web . Mvc . BackOfficeArea } ) } ,
{ "externalLinkLoginsUrl" , _linkGenerator . GetPathByAction ( nameof ( BackOfficeController . LinkLogin ) , backOfficeControllerName , new { area = Constants . Web . Mvc . BackOfficeArea } ) } ,
2020-05-25 23:15:32 +10:00
{ "gridConfig" , _linkGenerator . GetPathByAction ( nameof ( BackOfficeController . GetGridConfig ) , backOfficeControllerName , new { area = Constants . Web . Mvc . BackOfficeArea } ) } ,
2020-05-20 16:43:06 +10:00
// TODO: This is ultra confusing! this same key is used for different things, when returning the full app when authenticated it is this URL but when not auth'd it's actually the ServerVariables address
2020-05-25 23:15:32 +10:00
{ "serverVarsJs" , _linkGenerator . GetPathByAction ( nameof ( BackOfficeController . Application ) , backOfficeControllerName , new { area = Constants . Web . Mvc . BackOfficeArea } ) } ,
2020-05-20 16:43:06 +10:00
//API URLs
{
"packagesRestApiBaseUrl" , Constants . PackageRepository . RestApiBaseUrl
} ,
2020-06-03 19:52:43 +02:00
{
"redirectUrlManagementApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < RedirectUrlManagementController > (
controller = > controller . GetEnableState ( ) )
} ,
2020-05-25 23:15:32 +10:00
{
"tourApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < TourController > (
controller = > controller . GetTours ( ) )
} ,
2020-05-26 17:42:51 +10:00
{
"embedApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < RteEmbedController > (
2022-06-20 08:37:17 +02:00
controller = > controller . GetEmbed ( string . Empty , 0 , 0 ) )
2020-05-26 17:42:51 +10:00
} ,
2020-06-22 10:08:08 +02:00
{
"userApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < UsersController > (
2022-03-30 15:58:46 +02:00
controller = > controller . PostSaveUser ( new UserSave ( ) ) )
2020-06-22 10:08:08 +02:00
} ,
{
"userGroupsApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < UserGroupsController > (
2022-03-30 15:58:46 +02:00
controller = > controller . PostSaveUserGroup ( new UserGroupSave ( ) ) )
2020-06-22 10:08:08 +02:00
} ,
2020-06-09 13:48:50 +02:00
{
"contentApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < ContentController > (
2022-03-30 15:58:46 +02:00
controller = > controller . PostSave ( new ContentItemSave ( ) ) )
2020-06-09 13:48:50 +02:00
} ,
Implements Public Access in netcore (#10137)
* Getting new netcore PublicAccessChecker in place
* Adds full test coverage for PublicAccessChecker
* remove PublicAccessComposer
* adjust namespaces, ensure RoleManager works, separate public access controller, reduce content controller
* Implements the required methods on IMemberManager, removes old migrated code
* Updates routing to be able to re-route, Fixes middleware ordering ensuring endpoints are last, refactors pipeline options, adds public access middleware, ensures public access follows all hops
* adds note
* adds note
* Cleans up ext methods, ensures that members identity is added on both front-end and back ends. updates how UmbracoApplicationBuilder works in that it explicitly starts endpoints at the time of calling.
* Changes name to IUmbracoEndpointBuilder
* adds note
* Fixing tests, fixing error describers so there's 2x one for back office, one for members, fixes TryConvertTo, fixes login redirect
* fixing build
* Fixes keepalive, fixes PublicAccessMiddleware to not throw, updates startup code to be more clear and removes magic that registers middleware.
* adds note
* removes unused filter, fixes build
* fixes WebPath and tests
* Looks up entities in one query
* remove usings
* Fix test, remove stylesheet
* Set status code before we write to response to avoid error
* Ensures that users and members are validated when logging in. Shares more code between users and members.
* Fixes RepositoryCacheKeys to ensure the keys are normalized
* oops didn't mean to commit this
* Fix casing issues with caching, stop boxing value types for all cache operations, stop re-creating string keys in DefaultRepositoryCachePolicy
* bah, far out this keeps getting recommitted. sorry
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2021-04-20 15:11:45 +10:00
{
"publicAccessApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < PublicAccessController > (
controller = > controller . GetPublicAccess ( 0 ) )
} ,
2020-06-12 22:13:43 +02:00
{
"mediaApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < MediaController > (
controller = > controller . GetRootMedia ( ) )
} ,
2020-08-26 08:05:15 +02:00
{
"iconApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < IconController > (
2022-04-04 09:50:32 +02:00
controller = > controller . GetIcon ( string . Empty ) )
2020-08-26 08:05:15 +02:00
} ,
2020-05-25 23:15:32 +10:00
{
"imagesApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < ImagesController > (
2022-06-20 08:37:17 +02:00
controller = > controller . GetBigThumbnail ( string . Empty ) )
2020-05-25 23:15:32 +10:00
} ,
2020-06-11 08:00:35 +02:00
{
"sectionApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < SectionController > (
controller = > controller . GetSections ( ) )
} ,
{
"treeApplicationApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < ApplicationTreeController > (
2022-03-30 15:58:46 +02:00
controller = > controller . GetApplicationTrees ( string . Empty , string . Empty , FormCollection . Empty , TreeUse . None ) )
2020-06-11 08:00:35 +02:00
} ,
2020-06-12 22:13:43 +02:00
{
"contentTypeApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < ContentTypeController > (
controller = > controller . GetAllowedChildren ( 0 ) )
} ,
{
"mediaTypeApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < MediaTypeController > (
controller = > controller . GetAllowedChildren ( 0 ) )
} ,
2020-06-04 12:53:08 +02:00
{
"macroRenderingApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < MacroRenderingController > (
controller = > controller . GetMacroParameters ( 0 ) )
} ,
2020-06-03 20:39:54 +02:00
{
"macroApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < MacrosController > (
2022-03-30 15:58:46 +02:00
controller = > controller . Create ( string . Empty ) )
2020-06-03 20:39:54 +02:00
} ,
2020-05-25 23:15:32 +10:00
{
"authenticationApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < AuthenticationController > (
2022-03-30 15:58:46 +02:00
controller = > controller . PostLogin ( new LoginModel ( ) ) )
2020-05-25 23:15:32 +10:00
} ,
2022-04-19 08:33:03 +02:00
{
"twoFactorLoginApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < TwoFactorLoginController > (
2022-04-21 11:20:12 +02:00
controller = > controller . SetupInfo ( string . Empty ) )
2022-04-19 08:33:03 +02:00
} ,
2020-06-22 10:08:08 +02:00
{
"currentUserApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < CurrentUserController > (
2022-08-23 11:31:05 +02:00
controller = > controller . PostSetAvatar ( new List < IFormFile > ( ) ) )
2020-06-22 10:08:08 +02:00
} ,
2020-06-15 13:07:49 +02:00
{
"entityApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < EntityController > (
controller = > controller . GetById ( 0 , UmbracoEntityTypes . Media ) )
} ,
2020-06-03 19:52:43 +02:00
{
"dataTypeApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < DataTypeController > (
controller = > controller . GetById ( 0 ) )
} ,
2020-05-25 23:15:32 +10:00
{
"dashboardApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < DashboardController > (
2022-03-30 15:58:46 +02:00
controller = > controller . GetDashboard ( string . Empty ) )
2020-05-25 23:15:32 +10:00
} ,
2020-06-03 19:52:43 +02:00
{
"logApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < LogController > (
controller = > controller . GetPagedEntityLog ( 0 , 0 , 0 , Direction . Ascending , null ) )
} ,
2020-06-18 21:03:11 +02:00
{
"memberApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < MemberController > (
2022-04-04 09:50:32 +02:00
controller = > controller . GetByKey ( Guid . Empty ) )
2020-06-18 21:03:11 +02:00
} ,
2020-06-03 19:52:43 +02:00
{
"packageApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < PackageController > (
controller = > controller . GetCreatedPackages ( ) )
} ,
{
"relationApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < RelationController > (
2022-04-04 09:50:32 +02:00
controller = > controller . GetById ( 0 ) )
2020-06-03 19:52:43 +02:00
} ,
2020-05-26 17:42:51 +10:00
{
"rteApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < RichTextPreValueController > (
controller = > controller . GetConfiguration ( ) )
} ,
2020-06-03 19:52:43 +02:00
{
"stylesheetApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < StylesheetController > (
controller = > controller . GetAll ( ) )
} ,
2020-06-18 21:03:11 +02:00
{
"memberTypeApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < MemberTypeController > (
2022-06-07 11:16:30 +02:00
controller = > controller . GetById ( 0 ) )
2020-06-18 21:03:11 +02:00
} ,
2021-10-06 10:20:50 +02:00
{
"memberTypeQueryApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < MemberTypeQueryController > (
controller = > controller . GetAllTypes ( ) )
2020-06-18 21:03:11 +02:00
} ,
2020-06-22 10:08:08 +02:00
{
"memberGroupApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < MemberGroupController > (
controller = > controller . GetAllGroups ( ) )
} ,
2020-06-03 19:52:43 +02:00
{
"updateCheckApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < UpdateCheckController > (
controller = > controller . GetCheck ( ) )
} ,
{
"templateApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < TemplateController > (
controller = > controller . GetById ( 0 ) )
} ,
2020-06-09 07:49:26 +02:00
{
"memberTreeBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < MemberTreeController > (
2022-03-30 15:58:46 +02:00
controller = > controller . GetNodes ( "-1" , FormCollection . Empty ) )
2020-06-09 07:49:26 +02:00
} ,
{
"mediaTreeBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < MediaTreeController > (
2022-03-30 15:58:46 +02:00
controller = > controller . GetNodes ( "-1" , FormCollection . Empty ) )
2020-06-09 07:49:26 +02:00
} ,
{
"contentTreeBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < ContentTreeController > (
2022-03-30 15:58:46 +02:00
controller = > controller . GetNodes ( "-1" , FormCollection . Empty ) )
2020-06-09 07:49:26 +02:00
} ,
2020-05-26 17:42:51 +10:00
{
"tagsDataBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < TagsDataController > (
2022-06-20 08:37:17 +02:00
controller = > controller . GetTags ( string . Empty , string . Empty , null ) )
2020-05-26 17:42:51 +10:00
} ,
2020-05-25 23:15:32 +10:00
{
"examineMgmtBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < ExamineManagementController > (
controller = > controller . GetIndexerDetails ( ) )
} ,
2020-05-26 17:42:51 +10:00
{
"healthCheckBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < HealthCheckController > (
controller = > controller . GetAllHealthChecks ( ) )
} ,
2020-06-22 10:08:08 +02:00
{
"templateQueryApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < TemplateQueryController > (
2022-03-30 15:58:46 +02:00
controller = > controller . PostTemplateQuery ( new QueryModel ( ) ) )
2020-06-22 10:08:08 +02:00
} ,
2020-06-03 19:52:43 +02:00
{
"codeFileApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < CodeFileController > (
2022-06-20 08:37:17 +02:00
controller = > controller . GetByPath ( string . Empty , string . Empty ) )
2020-06-03 19:52:43 +02:00
} ,
{
"publishedStatusBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < PublishedStatusController > (
controller = > controller . GetPublishedStatusUrl ( ) )
} ,
{
"dictionaryApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < DictionaryController > (
controller = > controller . DeleteById ( int . MaxValue ) )
} ,
{
"publishedSnapshotCacheStatusBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < PublishedSnapshotCacheStatusController > (
controller = > controller . GetStatus ( ) )
} ,
2020-05-25 23:15:32 +10:00
{
"helpApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < HelpController > (
2022-06-20 08:37:17 +02:00
controller = > controller . GetContextHelpForPage ( string . Empty , string . Empty , string . Empty ) )
2020-05-25 23:15:32 +10:00
} ,
2020-06-03 19:52:43 +02:00
{
"backOfficeAssetsApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < BackOfficeAssetsController > (
controller = > controller . GetSupportedLocales ( ) )
} ,
{
"languageApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < LanguageController > (
2022-04-04 09:50:32 +02:00
controller = > controller . GetAllLanguages ( ) )
2020-06-03 19:52:43 +02:00
} ,
{
"relationTypeApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < RelationTypeController > (
controller = > controller . GetById ( 1 ) )
} ,
{
"logViewerApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < LogViewerController > (
controller = > controller . GetNumberOfErrors ( null , null ) )
} ,
2020-05-26 17:42:51 +10:00
{
"webProfilingBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < WebProfilingController > (
controller = > controller . GetStatus ( ) )
} ,
2020-06-03 19:52:43 +02:00
{
"tinyMceApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < TinyMceController > (
2022-03-30 15:58:46 +02:00
controller = > controller . UploadImage ( new FormFileCollection ( ) ) )
2020-06-03 19:52:43 +02:00
} ,
2020-05-25 23:15:32 +10:00
{
"imageUrlGeneratorApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < ImageUrlGeneratorController > (
2022-04-04 09:50:32 +02:00
controller = > controller . GetCropUrl ( string . Empty , null , null , null ) )
2020-05-25 23:15:32 +10:00
} ,
2020-08-07 14:00:56 +02:00
{
"elementTypeApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < ElementTypeController > (
controller = > controller . GetAll ( ) )
} ,
2020-09-30 10:02:28 +02:00
{
2020-10-01 07:03:31 +02:00
"previewHubUrl" , _previewRoutes . GetPreviewHubRoute ( )
2020-09-30 10:02:28 +02:00
} ,
2022-03-07 22:46:16 +01:00
{
"trackedReferencesApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < TrackedReferencesController > (
controller = > controller . GetPagedReferences ( 0 , 1 , 1 , false ) )
2022-04-19 15:06:10 +02:00
} ,
{
"analyticsApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < AnalyticsController > (
controller = > controller . GetConsentLevel ( ) )
} ,
2022-05-24 09:01:32 +02:00
{
"propertyTypeApiBaseUrl" , _linkGenerator . GetUmbracoApiServiceBaseUrl < PropertyTypeController > (
controller = > controller . HasValues ( string . Empty ) )
} ,
2020-05-20 16:43:06 +10:00
}
} ,
{
"umbracoSettings" , new Dictionary < string , object >
{
{ "umbracoPath" , _globalSettings . GetBackOfficePath ( _hostingEnvironment ) } ,
2021-03-05 15:36:27 +01:00
{ "mediaPath" , _hostingEnvironment . ToAbsolute ( globalSettings . UmbracoMediaPath ) . TrimEnd ( Constants . CharArrays . ForwardSlash ) } ,
{ "appPluginsPath" , _hostingEnvironment . ToAbsolute ( Constants . SystemDirectories . AppPlugins ) . TrimEnd ( Constants . CharArrays . ForwardSlash ) } ,
2020-05-20 16:43:06 +10:00
{
"imageFileTypes" ,
2020-09-22 15:06:03 +02:00
string . Join ( "," , _imageUrlGenerator . SupportedImageFileTypes )
2020-05-20 16:43:06 +10:00
} ,
{
"disallowedUploadFiles" ,
string . Join ( "," , _contentSettings . DisallowedUploadFiles )
} ,
{
"allowedUploadFiles" ,
string . Join ( "," , _contentSettings . AllowedUploadFiles )
} ,
{
"maxFileSize" ,
GetMaxRequestLength ( )
} ,
{ "keepUserLoggedIn" , _securitySettings . KeepUserLoggedIn } ,
{ "usernameIsEmail" , _securitySettings . UsernameIsEmail } ,
2021-03-05 15:36:27 +01:00
{ "cssPath" , _hostingEnvironment . ToAbsolute ( globalSettings . UmbracoCssPath ) . TrimEnd ( Constants . CharArrays . ForwardSlash ) } ,
2020-05-20 16:43:06 +10:00
{ "allowPasswordReset" , _securitySettings . AllowPasswordReset } ,
{ "loginBackgroundImage" , _contentSettings . LoginBackgroundImage } ,
2021-01-18 15:40:22 +01:00
{ "loginLogoImage" , _contentSettings . LoginLogoImage } ,
2022-02-15 14:10:17 +01:00
{ "hideBackofficeLogo" , _contentSettings . HideBackOfficeLogo } ,
2022-03-07 22:46:16 +01:00
{ "disableDeleteWhenReferenced" , _contentSettings . DisableDeleteWhenReferenced } ,
{ "disableUnpublishWhenReferenced" , _contentSettings . DisableUnpublishWhenReferenced } ,
2021-02-25 15:08:56 +01:00
{ "showUserInvite" , _emailSender . CanSendRequiredEmail ( ) } ,
{ "canSendRequiredEmail" , _emailSender . CanSendRequiredEmail ( ) } ,
2020-05-20 16:43:06 +10:00
{ "showAllowSegmentationForDocumentTypes" , false } ,
2021-04-20 19:34:18 +02:00
{ "minimumPasswordLength" , _memberPasswordConfigurationSettings . RequiredLength } ,
{ "minimumPasswordNonAlphaNum" , _memberPasswordConfigurationSettings . GetMinNonAlphaNumericChars ( ) } ,
2022-05-12 12:41:51 +02:00
{ "sanitizeTinyMce" , _globalSettings . SanitizeTinyMce } ,
2022-06-20 13:59:18 +02:00
{ "dataTypesCanBeChanged" , _dataTypesSettings . CanBeChanged . ToString ( ) } ,
2022-09-07 14:38:54 +02:00
{ "allowEditInvariantFromNonDefault" , _contentSettings . AllowEditInvariantFromNonDefault } ,
2020-05-20 16:43:06 +10:00
}
} ,
{
"umbracoPlugins" , new Dictionary < string , object >
{
// for each tree that is [PluginController], get
// alias -> areaName
// so that routing (route.js) can look for views
{ "trees" , GetPluginTrees ( ) . ToArray ( ) }
}
} ,
{
"isDebuggingEnabled" , _hostingEnvironment . IsDebugMode
} ,
{
"application" , GetApplicationState ( )
} ,
{
"externalLogins" , new Dictionary < string , object >
{
{
2020-11-27 13:34:32 +01:00
// TODO: It would be nicer to not have to manually translate these properties
// but then needs to be changed in quite a few places in angular
2021-07-27 16:12:23 -06:00
"providers" , ( await _externalLogins . GetBackOfficeProvidersAsync ( ) )
2020-05-20 16:43:06 +10:00
. Select ( p = > new
{
2021-07-27 16:12:23 -06:00
authType = p . ExternalLoginProvider . AuthenticationType ,
caption = p . AuthenticationScheme . DisplayName ,
properties = p . ExternalLoginProvider . Options
2020-05-20 16:43:06 +10:00
} )
. ToArray ( )
}
}
} ,
{
"features" , new Dictionary < string , object >
{
{
"disabledFeatures" , new Dictionary < string , object >
{
{ "disableTemplates" , _features . Disabled . DisableTemplates }
}
}
}
}
} ;
2021-07-27 16:12:23 -06:00
return defaultVals ;
2020-05-20 16:43:06 +10:00
}
[DataContract]
private class PluginTree
{
[DataMember(Name = "alias")]
2022-03-30 15:58:46 +02:00
public string? Alias { get ; set ; }
2020-05-20 16:43:06 +10:00
[DataMember(Name = "packageFolder")]
2022-03-30 15:58:46 +02:00
public string? PackageFolder { get ; set ; }
2020-05-20 16:43:06 +10:00
}
private IEnumerable < PluginTree > GetPluginTrees ( )
{
// used to be (cached)
//var treeTypes = Current.TypeLoader.GetAttributedTreeControllers();
//
// ie inheriting from TreeController and marked with TreeAttribute
//
// do this instead
// inheriting from TreeControllerBase and marked with TreeAttribute
2022-06-20 08:37:17 +02:00
foreach ( Tree tree in _treeCollection )
2020-06-09 07:49:26 +02:00
{
2022-06-20 08:37:17 +02:00
Type treeType = tree . TreeControllerType ;
2020-05-20 16:43:06 +10:00
2020-06-09 07:49:26 +02:00
// exclude anything marked with CoreTreeAttribute
2022-06-20 08:37:17 +02:00
CoreTreeAttribute ? coreTree = treeType . GetCustomAttribute < CoreTreeAttribute > ( false ) ;
2021-09-23 10:30:22 +02:00
if ( coreTree ! = null )
2022-06-20 08:37:17 +02:00
{
2021-09-23 10:30:22 +02:00
continue ;
2022-06-20 08:37:17 +02:00
}
2020-05-20 16:43:06 +10:00
2020-06-09 07:49:26 +02:00
// exclude anything not marked with PluginControllerAttribute
2022-06-20 08:37:17 +02:00
PluginControllerAttribute ? pluginController = treeType . GetCustomAttribute < PluginControllerAttribute > ( false ) ;
2021-09-23 10:30:22 +02:00
if ( pluginController = = null )
2022-06-20 08:37:17 +02:00
{
2021-09-23 10:30:22 +02:00
continue ;
2022-06-20 08:37:17 +02:00
}
2020-05-20 16:43:06 +10:00
2020-06-09 07:49:26 +02:00
yield return new PluginTree { Alias = tree . TreeAlias , PackageFolder = pluginController . AreaName } ;
}
2020-05-20 16:43:06 +10:00
}
/// <summary>
/// Returns the server variables regarding the application state
/// </summary>
/// <returns></returns>
2022-03-30 15:58:46 +02:00
private Dictionary < string , object? > GetApplicationState ( )
2020-05-20 16:43:06 +10:00
{
2021-05-12 09:41:40 +02:00
var version = _runtimeState . SemanticVersion . ToSemanticStringWithoutBuild ( ) ;
2022-03-30 15:58:46 +02:00
var app = new Dictionary < string , object? >
2020-05-20 16:43:06 +10:00
{
// add versions - see UmbracoVersion for details & differences
// the complete application version (eg "8.1.2-alpha.25")
2021-05-12 09:41:40 +02:00
{ "version" , version } ,
2020-05-20 16:43:06 +10:00
// the assembly version (eg "8.0.0")
2022-03-30 15:58:46 +02:00
{ "assemblyVersion" , _umbracoVersion . AssemblyVersion ? . ToString ( ) }
2020-05-20 16:43:06 +10:00
} ;
2022-07-14 22:48:43 +02:00
app . Add ( "runtimeMode" , _runtimeSettings . Mode . ToString ( ) ) ;
2020-05-20 16:43:06 +10:00
//the value is the hash of the version, cdf version and the configured state
app . Add ( "cacheBuster" , $"{version}.{_runtimeState.Level}.{_runtimeMinifier.CacheBuster}" . GenerateHash ( ) ) ;
//useful for dealing with virtual paths on the client side when hosted in virtual directories especially
app . Add ( "applicationPath" , _httpContextAccessor . GetRequiredHttpContext ( ) . Request . PathBase . ToString ( ) . EnsureEndsWith ( '/' ) ) ;
//add the server's GMT time offset in minutes
app . Add ( "serverTimeOffset" , Convert . ToInt32 ( DateTimeOffset . Now . Offset . TotalMinutes ) ) ;
return app ;
}
private string GetMaxRequestLength ( )
{
2020-08-20 22:18:50 +01:00
return _runtimeSettings . MaxRequestLength . HasValue ? _runtimeSettings . MaxRequestLength . Value . ToString ( ) : string . Empty ;
2020-05-20 16:43:06 +10:00
}
}
}