Merge remote-tracking branch 'origin/dev-v7' into temp8
# Conflicts: # build/Modules/Umbraco.Build/Get-UmbracoBuildEnv.ps1 # build/NuSpecs/UmbracoCms.Core.nuspec # build/NuSpecs/UmbracoCms.nuspec # build/NuSpecs/tools/Readme.txt # src/Umbraco.Core/Configuration/UmbracoConfig.cs # src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs # src/Umbraco.Core/Configuration/UmbracoSettings/IContentSection.cs # src/Umbraco.Core/Constants-Conventions.cs # src/Umbraco.Core/Constants-System.cs # src/Umbraco.Core/IO/MediaFileSystem.cs # src/Umbraco.Core/Media/Exif/ImageFile.cs # src/Umbraco.Core/Models/Property.cs # src/Umbraco.Core/Models/PropertyTagBehavior.cs # src/Umbraco.Core/Models/PropertyTags.cs # src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/SetDefaultTagsStorageType.cs # src/Umbraco.Core/Persistence/Repositories/AuditRepository.cs # src/Umbraco.Core/Persistence/Repositories/UserRepository.cs # src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs # src/Umbraco.Core/Security/AuthenticationExtensions.cs # src/Umbraco.Core/Security/BackOfficeCookieAuthenticationProvider.cs # src/Umbraco.Core/Services/Implement/PackagingService.cs # src/Umbraco.Core/Services/ServerRegistrationService.cs # src/Umbraco.Core/StringExtensions.cs # src/Umbraco.Core/packages.config # src/Umbraco.Tests/ApplicationUrlHelperTests.cs # src/Umbraco.Tests/Persistence/Repositories/AuditRepositoryTest.cs # src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs # src/Umbraco.Tests/Web/TemplateUtilitiesTests.cs # src/Umbraco.Tests/packages.config # src/Umbraco.Web.UI.Client/package.json # src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js # src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js # src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js # src/Umbraco.Web.UI.Client/src/common/resources/log.resource.js # src/Umbraco.Web.UI.Client/src/common/services/user.service.js # src/Umbraco.Web.UI.Client/src/less/belle.less # src/Umbraco.Web.UI.Client/src/less/components/card.less # src/Umbraco.Web.UI.Client/src/less/navs.less # src/Umbraco.Web.UI.Client/src/less/panel.less # src/Umbraco.Web.UI.Client/src/less/property-editors.less # src/Umbraco.Web.UI.Client/src/less/tree.less # src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.controller.js # src/Umbraco.Web.UI.Client/src/views/common/dialogs/login.html # src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.controller.js # src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.controller.js # src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.html # src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.controller.js # src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.html # src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html # src/Umbraco.Web.UI.Client/src/views/components/notifications/umb-notifications.html # src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html # src/Umbraco.Web.UI.Client/src/views/components/umb-table.html # src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html # src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js # src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js # src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html # src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js # src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html # src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js # src/Umbraco.Web.UI.Client/src/views/propertyeditors/textarea/textarea.html # src/Umbraco.Web.UI/Umbraco/config/lang/en.xml # src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml # src/Umbraco.Web.UI/config/umbracoSettings.Release.config # src/Umbraco.Web.UI/packages.config # src/Umbraco.Web.UI/web.Template.Debug.config # src/Umbraco.Web.UI/web.Template.config # src/Umbraco.Web/Editors/AuthenticationController.cs # src/Umbraco.Web/Editors/BackOfficeController.cs # src/Umbraco.Web/Editors/CanvasDesignerController.cs # src/Umbraco.Web/Editors/ContentController.cs # src/Umbraco.Web/Editors/DashboardController.cs # src/Umbraco.Web/Editors/LogController.cs # src/Umbraco.Web/Editors/MediaController.cs # src/Umbraco.Web/Install/InstallHelper.cs # src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs # src/Umbraco.Web/Media/EmbedProviders/AbstractOEmbedProvider.cs # src/Umbraco.Web/Models/Mapping/DataTypeModelMapper.cs # src/Umbraco.Web/Models/Mapping/PreValueDisplayResolver.cs # src/Umbraco.Web/Mvc/MasterControllerFactory.cs # src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs # src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs # src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs # src/Umbraco.Web/PropertyEditors/ValueConverters/MultiNodeTreePickerPropertyConverter.cs # src/Umbraco.Web/PublishedCache/MemberPublishedContent.cs # src/Umbraco.Web/Routing/RedirectTrackingEventHandler.cs # src/Umbraco.Web/Scheduling/HealthCheckNotifier.cs # src/Umbraco.Web/Scheduling/KeepAlive.cs # src/Umbraco.Web/Scheduling/LogScrubber.cs # src/Umbraco.Web/Scheduling/ScheduledPublishing.cs # src/Umbraco.Web/Scheduling/ScheduledTasks.cs # src/Umbraco.Web/Scheduling/Scheduler.cs # src/Umbraco.Web/Templates/TemplateUtilities.cs # src/Umbraco.Web/Trees/DataTypeTreeController.cs # src/Umbraco.Web/UmbracoModule.cs # src/Umbraco.Web/_Legacy/Packager/Installer.cs # src/Umbraco.Web/packages.config # src/Umbraco.Web/umbraco.presentation/keepAliveService.cs # src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/FeedProxy.aspx.cs # src/umbraco.businesslogic/IO/IOHelper.cs # src/umbraco.cms/packages.config # src/umbraco.cms/umbraco.cms.csproj # src/umbraco.controls/packages.config # src/umbraco.controls/umbraco.controls.csproj # src/umbraco.editorControls/packages.config # src/umbraco.editorControls/umbraco.editorControls.csproj
This commit is contained in:
@@ -421,6 +421,34 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
}
|
||||
|
||||
//They've successfully set their password, we can now update their user account to be confirmed
|
||||
//if user was only invited, then they have not been approved
|
||||
//but a successful forgot password flow (e.g. if their token had expired and they did a forgot password instead of request new invite)
|
||||
//means we have verified their email
|
||||
if (!UserManager.IsEmailConfirmed(model.UserId))
|
||||
{
|
||||
await UserManager.ConfirmEmailAsync(model.UserId, model.ResetCode);
|
||||
}
|
||||
|
||||
//if the user is invited, enable their account on forgot password
|
||||
var identityUser = await UserManager.FindByIdAsync(model.UserId);
|
||||
//invited is not approved, never logged in, invited date present
|
||||
/*
|
||||
if (LastLoginDate == default && IsApproved == false && InvitedDate != null)
|
||||
return UserState.Invited;
|
||||
*/
|
||||
if (identityUser != null && !identityUser.IsApproved)
|
||||
{
|
||||
var user = Services.UserService.GetByUsername(identityUser.UserName);
|
||||
//also check InvitedDate and never logged in, otherwise this would allow a disabled user to reactivate their account with a forgot password
|
||||
if (user.LastLoginDate == default && user.InvitedDate != null)
|
||||
{
|
||||
user.IsApproved = true;
|
||||
user.InvitedDate = null;
|
||||
Services.UserService.Save(user);
|
||||
}
|
||||
}
|
||||
|
||||
UserManager.RaiseForgotPasswordChangedSuccessEvent(model.UserId);
|
||||
return Request.CreateResponse(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
@@ -82,6 +82,16 @@ namespace Umbraco.Web.Editors
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> VerifyInvite(string invite)
|
||||
{
|
||||
//if you are hitting VerifyInvite, you're already signed in as a different user, and the token is invalid
|
||||
//you'll exit on one of the return RedirectToAction("Default") but you're still logged in so you just get
|
||||
//dumped at the default admin view with no detail
|
||||
if(Security.IsAuthenticated())
|
||||
{
|
||||
AuthenticationManager.SignOut(
|
||||
Core.Constants.Security.BackOfficeAuthenticationType,
|
||||
Core.Constants.Security.BackOfficeExternalAuthenticationType);
|
||||
}
|
||||
|
||||
if (invite == null)
|
||||
{
|
||||
Logger.Warn<BackOfficeController>("VerifyUser endpoint reached with invalid token: NULL");
|
||||
@@ -125,16 +135,15 @@ namespace Umbraco.Web.Editors
|
||||
if (result.Succeeded == false)
|
||||
{
|
||||
Logger.Warn<BackOfficeController>("Could not verify email, Error: " + string.Join(",", result.Errors) + ", Token: " + invite);
|
||||
return RedirectToAction("Default");
|
||||
return new RedirectResult(Url.Action("Default") + "#/login/false?invite=3");
|
||||
}
|
||||
|
||||
//sign the user in
|
||||
|
||||
AuthenticationManager.SignOut(
|
||||
Core.Constants.Security.BackOfficeAuthenticationType,
|
||||
Core.Constants.Security.BackOfficeExternalAuthenticationType);
|
||||
|
||||
DateTime? previousLastLoginDate = identityUser.LastLoginDateUtc;
|
||||
await SignInManager.SignInAsync(identityUser, false, false);
|
||||
//reset the lastlogindate back to previous as the user hasn't actually logged in, to add a flag or similar to SignInManager would be a breaking change
|
||||
identityUser.LastLoginDateUtc = previousLastLoginDate;
|
||||
await UserManager.UpdateAsync(identityUser);
|
||||
|
||||
return new RedirectResult(Url.Action("Default") + "#/login/false?invite=1");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
@@ -585,6 +586,17 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
private ContentItemDisplay PostSaveInternal(ContentItemSave contentItem, Func<IContent, OperationResult> saveMethod)
|
||||
{
|
||||
//Recent versions of IE/Edge may send in the full clientside file path instead of just the file name.
|
||||
//To ensure similar behavior across all browsers no matter what they do - we strip the FileName property of all
|
||||
//uploaded files to being *only* the actual file name (as it should be).
|
||||
if (contentItem.UploadedFiles != null && contentItem.UploadedFiles.Any())
|
||||
{
|
||||
foreach (var file in contentItem.UploadedFiles)
|
||||
{
|
||||
file.FileName = Path.GetFileName(file.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
//If we've reached here it means:
|
||||
// * Our model has been bound
|
||||
// * and validated
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace Umbraco.Web.Editors
|
||||
[WebApi.UmbracoAuthorize]
|
||||
public class DashboardController : UmbracoApiController
|
||||
{
|
||||
//we have just one instance of HttpClient shared for the entire application
|
||||
private static readonly HttpClient HttpClient = new HttpClient();
|
||||
//we have baseurl as a param to make previewing easier, so we can test with a dev domain from client side
|
||||
[ValidateAngularAntiForgeryToken]
|
||||
public async Task<JObject> GetRemoteDashboardContent(string section, string baseUrl = "https://dashboard.umbraco.org/")
|
||||
@@ -54,13 +56,10 @@ namespace Umbraco.Web.Editors
|
||||
//content is null, go get it
|
||||
try
|
||||
{
|
||||
using (var web = new HttpClient())
|
||||
{
|
||||
//fetch dashboard json and parse to JObject
|
||||
var json = await web.GetStringAsync(url);
|
||||
content = JObject.Parse(json);
|
||||
result = content;
|
||||
}
|
||||
//fetch dashboard json and parse to JObject
|
||||
var json = await HttpClient.GetStringAsync(url);
|
||||
content = JObject.Parse(json);
|
||||
result = content;
|
||||
|
||||
ApplicationCache.RuntimeCache.InsertCacheItem<JObject>(key, () => result, new TimeSpan(0, 30, 0));
|
||||
}
|
||||
@@ -93,17 +92,14 @@ namespace Umbraco.Web.Editors
|
||||
//content is null, go get it
|
||||
try
|
||||
{
|
||||
using (var web = new HttpClient())
|
||||
{
|
||||
//fetch remote css
|
||||
content = await web.GetStringAsync(url);
|
||||
//fetch remote css
|
||||
content = await HttpClient.GetStringAsync(url);
|
||||
|
||||
//can't use content directly, modified closure problem
|
||||
result = content;
|
||||
//can't use content directly, modified closure problem
|
||||
result = content;
|
||||
|
||||
//save server content for 30 mins
|
||||
//save server content for 30 mins
|
||||
ApplicationCache.RuntimeCache.InsertCacheItem<string>(key, () => result, new TimeSpan(0, 30, 0));
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
|
||||
@@ -7,20 +7,22 @@ using System.Threading.Tasks;
|
||||
namespace Umbraco.Web.Editors
|
||||
{
|
||||
public class HelpController : UmbracoAuthorizedJsonController
|
||||
{
|
||||
{
|
||||
private static HttpClient _httpClient;
|
||||
public async Task<List<HelpPage>> GetContextHelpForPage(string section, string tree, string baseUrl = "https://our.umbraco.com")
|
||||
{
|
||||
var url = string.Format(baseUrl + "/Umbraco/Documentation/Lessons/GetContextHelpDocs?sectionAlias={0}&treeAlias={1}", section, tree);
|
||||
using (var web = new HttpClient())
|
||||
{
|
||||
//fetch dashboard json and parse to JObject
|
||||
var json = await web.GetStringAsync(url);
|
||||
var result = JsonConvert.DeserializeObject<List<HelpPage>>(json);
|
||||
if (result != null)
|
||||
return result;
|
||||
|
||||
return new List<HelpPage>();
|
||||
}
|
||||
if (_httpClient == null)
|
||||
_httpClient = new HttpClient();
|
||||
|
||||
//fetch dashboard json and parse to JObject
|
||||
var json = await _httpClient.GetStringAsync(url);
|
||||
var result = JsonConvert.DeserializeObject<List<HelpPage>>(json);
|
||||
if (result != null)
|
||||
return result;
|
||||
|
||||
return new List<HelpPage>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using AutoMapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AutoMapper;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
@@ -45,7 +46,7 @@ namespace Umbraco.Web.Editors
|
||||
var userId = Security.GetUserId().ResultOr(0);
|
||||
var result = Services.AuditService.GetPagedItemsByUser(userId, pageNumber - 1, pageSize, out totalRecords, orderDirection, customFilter:dateQuery);
|
||||
var mapped = Mapper.Map<IEnumerable<AuditLog>>(result);
|
||||
return new PagedResult<AuditLog>(totalRecords, pageNumber + 1, pageSize)
|
||||
return new PagedResult<AuditLog>(totalRecords, pageNumber, pageSize)
|
||||
{
|
||||
Items = MapAvatarsAndNames(mapped)
|
||||
};
|
||||
|
||||
@@ -439,6 +439,17 @@ namespace Umbraco.Web.Editors
|
||||
[ModelBinder(typeof(MediaItemBinder))]
|
||||
MediaItemSave contentItem)
|
||||
{
|
||||
//Recent versions of IE/Edge may send in the full clientside file path instead of just the file name.
|
||||
//To ensure similar behavior across all browsers no matter what they do - we strip the FileName property of all
|
||||
//uploaded files to being *only* the actual file name (as it should be).
|
||||
if (contentItem.UploadedFiles != null && contentItem.UploadedFiles.Any())
|
||||
{
|
||||
foreach (var file in contentItem.UploadedFiles)
|
||||
{
|
||||
file.FileName = Path.GetFileName(file.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
//If we've reached here it means:
|
||||
// * Our model has been bound
|
||||
// * and validated
|
||||
@@ -688,15 +699,7 @@ namespace Umbraco.Web.Editors
|
||||
mediaType = result.FormData["contentTypeAlias"];
|
||||
}
|
||||
|
||||
//TODO: make the media item name "nice" since file names could be pretty ugly, we have
|
||||
// string extensions to do much of this but we'll need:
|
||||
// * Pascalcase the name (use string extensions)
|
||||
// * strip the file extension
|
||||
// * underscores to spaces
|
||||
// * probably remove 'ugly' characters - let's discuss
|
||||
// All of this logic should exist in a string extensions method and be unit tested
|
||||
// http://issues.umbraco.org/issue/U4-5572
|
||||
var mediaItemName = fileName;
|
||||
var mediaItemName = fileName.ToFriendlyName();
|
||||
|
||||
var f = mediaService.CreateMedia(mediaItemName, parentId, mediaType, Security.CurrentUser.Id);
|
||||
|
||||
@@ -910,4 +913,4 @@ namespace Umbraco.Web.Editors
|
||||
return hasPathAccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi;
|
||||
using File = System.IO.File;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
{
|
||||
@@ -63,7 +64,28 @@ namespace Umbraco.Web.Editors
|
||||
return searchResult;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This lists the RedirectUrls for a particular content item
|
||||
/// Do we need to consider paging here?
|
||||
/// </summary>
|
||||
/// <param name="contentUdi">Udi of content item to retrieve RedirectUrls for</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public RedirectUrlSearchResult RedirectUrlsForContentItem(string contentUdi)
|
||||
{
|
||||
var redirectsResult = new RedirectUrlSearchResult();
|
||||
if (GuidUdi.TryParse(contentUdi, out var guidIdi))
|
||||
{
|
||||
var redirectUrlService = Services.RedirectUrlService;
|
||||
var redirects = redirectUrlService.GetContentRedirectUrls(guidIdi.Guid);
|
||||
redirectsResult.SearchResults = Mapper.Map<IEnumerable<ContentRedirectUrl>>(redirects).ToArray();
|
||||
//not doing paging 'yet'
|
||||
redirectsResult.TotalCount = redirects.Count();
|
||||
redirectsResult.CurrentPage = 1;
|
||||
redirectsResult.PageCount = 1;
|
||||
}
|
||||
return redirectsResult;
|
||||
}
|
||||
[HttpPost]
|
||||
public IHttpActionResult DeleteRedirectUrl(Guid id)
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Umbraco.Web.Install
|
||||
{
|
||||
public sealed class InstallHelper
|
||||
{
|
||||
private static HttpClient _httpClient;
|
||||
private readonly DatabaseBuilder _databaseBuilder;
|
||||
private readonly HttpContextBase _httpContext;
|
||||
private readonly ILogger _logger;
|
||||
@@ -168,16 +169,17 @@ namespace Umbraco.Web.Install
|
||||
|
||||
internal IEnumerable<Package> GetStarterKits()
|
||||
{
|
||||
var packages = new List<Package>();
|
||||
if (_httpClient == null)
|
||||
_httpClient = new HttpClient();
|
||||
|
||||
var packages = new List<Package>();
|
||||
try
|
||||
{
|
||||
var requestUri = $"https://our.umbraco.com/webapi/StarterKit/Get/?umbracoVersion={UmbracoVersion.Current}";
|
||||
|
||||
using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
|
||||
using (var httpClient = new HttpClient())
|
||||
using (var response = httpClient.SendAsync(request).Result)
|
||||
{
|
||||
var response = _httpClient.SendAsync(request).Result;
|
||||
packages = response.Content.ReadAsAsync<IEnumerable<Package>>().Result.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Security;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Migrations.Install;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Install.Models;
|
||||
|
||||
@@ -27,6 +29,7 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
private readonly HttpContextBase _http;
|
||||
private readonly IUserService _userService;
|
||||
private readonly DatabaseBuilder _databaseBuilder;
|
||||
private static HttpClient _httpClient;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
|
||||
public NewInstallStep(HttpContextBase http, IUserService userService, DatabaseBuilder databaseBuilder, IGlobalSettings globalSettings)
|
||||
@@ -79,15 +82,18 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
admin.Username = user.Email.Trim();
|
||||
|
||||
_userService.Save(admin);
|
||||
|
||||
|
||||
|
||||
if (user.SubscribeToNewsLetter)
|
||||
{
|
||||
if (_httpClient == null)
|
||||
_httpClient = new HttpClient();
|
||||
|
||||
var values = new NameValueCollection { { "name", admin.Name }, { "email", admin.Email } };
|
||||
var content = new StringContent(JsonConvert.SerializeObject(values), Encoding.UTF8, "application/json");
|
||||
|
||||
try
|
||||
{
|
||||
var client = new System.Net.WebClient();
|
||||
var values = new NameValueCollection { { "name", admin.Name }, { "email", admin.Email} };
|
||||
client.UploadValues("https://shop.umbraco.com/base/Ecom/SubmitEmail/installer.aspx", values);
|
||||
var response = _httpClient.PostAsync("https://shop.umbraco.com/base/Ecom/SubmitEmail/installer.aspx", content).Result;
|
||||
}
|
||||
catch { /* fail in silence */ }
|
||||
}
|
||||
@@ -114,11 +120,14 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
|
||||
public override string View
|
||||
{
|
||||
get { return RequiresExecution(null)
|
||||
//the user UI
|
||||
get
|
||||
{
|
||||
return RequiresExecution(null)
|
||||
//the user UI
|
||||
? "user"
|
||||
//the continue install UI
|
||||
: "continueinstall"; }
|
||||
//the continue install UI
|
||||
: "continueinstall";
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RequiresExecution(UserModel model)
|
||||
|
||||
@@ -12,18 +12,20 @@ namespace Umbraco.Web.Media.EmbedProviders
|
||||
{
|
||||
//TODO: Make all Http calls async
|
||||
|
||||
public abstract class AbstractOEmbedProvider: IEmbedProvider
|
||||
public abstract class AbstractOEmbedProvider : IEmbedProvider
|
||||
{
|
||||
private static HttpClient _httpClient;
|
||||
|
||||
public virtual bool SupportsDimensions
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[ProviderSetting]
|
||||
public string APIEndpoint{ get;set; }
|
||||
public string APIEndpoint { get; set; }
|
||||
|
||||
[ProviderSetting]
|
||||
public Dictionary<string, string> RequestParams{ get;set; }
|
||||
public Dictionary<string, string> RequestParams { get; set; }
|
||||
|
||||
public abstract string GetMarkup(string url, int maxWidth, int maxHeight);
|
||||
|
||||
@@ -51,9 +53,13 @@ namespace Umbraco.Web.Media.EmbedProviders
|
||||
|
||||
public virtual string DownloadResponse(string url)
|
||||
{
|
||||
using (var webClient = new WebClient())
|
||||
if (_httpClient == null)
|
||||
_httpClient = new HttpClient();
|
||||
|
||||
using (var request = new HttpRequestMessage(HttpMethod.Get, url))
|
||||
{
|
||||
return webClient.DownloadString(url);
|
||||
var response = _httpClient.SendAsync(request).Result;
|
||||
return response.Content.ReadAsStringAsync().Result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,5 +17,9 @@
|
||||
/// The file is a TIFF File.
|
||||
/// </summary>
|
||||
TIFF,
|
||||
/// <summary>
|
||||
/// The file is a SVG File.
|
||||
/// </summary>
|
||||
SVG,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Umbraco.Web.Scheduling
|
||||
switch (_runtimeState.ServerRole)
|
||||
{
|
||||
case ServerRole.Replica:
|
||||
_logger.Debug<HealthCheckNotifier>("Does not run on slave servers.");
|
||||
_logger.Debug<HealthCheckNotifier>("Does not run on replica servers.");
|
||||
return true; // DO repeat, server role can change
|
||||
case ServerRole.Unknown:
|
||||
_logger.Debug<HealthCheckNotifier>("Does not run on servers with unknown role.");
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Umbraco.Web.Scheduling
|
||||
switch (_runtime.ServerRole)
|
||||
{
|
||||
case ServerRole.Replica:
|
||||
_logger.Debug<KeepAlive>("Does not run on slave servers.");
|
||||
_logger.Debug<KeepAlive>("Does not run on replica servers.");
|
||||
return true; // role may change!
|
||||
case ServerRole.Unknown:
|
||||
_logger.Debug<KeepAlive>("Does not run on servers with unknown role.");
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Umbraco.Web.Scheduling
|
||||
switch (_runtime.ServerRole)
|
||||
{
|
||||
case ServerRole.Replica:
|
||||
_logger.Debug<LogScrubber>("Does not run on slave servers.");
|
||||
_logger.Debug<LogScrubber>("Does not run on replica servers.");
|
||||
return true; // DO repeat, server role can change
|
||||
case ServerRole.Unknown:
|
||||
_logger.Debug<LogScrubber>("Does not run on servers with unknown role.");
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Umbraco.Web.Scheduling
|
||||
switch (_runtime.ServerRole)
|
||||
{
|
||||
case ServerRole.Replica:
|
||||
_logger.Debug<ScheduledPublishing>("Does not run on slave servers.");
|
||||
_logger.Debug<ScheduledPublishing>("Does not run on replica servers.");
|
||||
return true; // DO repeat, server role can change
|
||||
case ServerRole.Unknown:
|
||||
_logger.Debug<ScheduledPublishing>("Does not run on servers with unknown role.");
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace Umbraco.Web.Scheduling
|
||||
|
||||
internal class ScheduledTasks : RecurringTaskBase
|
||||
{
|
||||
private static HttpClient _httpClient;
|
||||
private readonly IRuntimeState _runtime;
|
||||
private readonly IUmbracoSettingsSection _settings;
|
||||
private readonly ILogger _logger;
|
||||
@@ -65,27 +66,28 @@ namespace Umbraco.Web.Scheduling
|
||||
|
||||
private async Task<bool> GetTaskByHttpAync(string url, CancellationToken token)
|
||||
{
|
||||
using (var wc = new HttpClient())
|
||||
if (_httpClient == null)
|
||||
_httpClient = new HttpClient();
|
||||
|
||||
if (Uri.TryCreate(_runtime.ApplicationUrl, UriKind.Absolute, out var baseUri))
|
||||
_httpClient.BaseAddress = baseUri;
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
|
||||
//TODO: pass custom the authorization header, currently these aren't really secured!
|
||||
//request.Headers.Authorization = AdminTokenAuthorizeAttribute.GetAuthenticationHeaderValue(_appContext);
|
||||
|
||||
try
|
||||
{
|
||||
// url could be relative, so better set a base url for the http client
|
||||
wc.BaseAddress = _runtime.ApplicationUrl;
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
|
||||
//TODO: pass custom the authorization header, currently these aren't really secured!
|
||||
//request.Headers.Authorization = AdminTokenAuthorizeAttribute.GetAuthenticationHeaderValue(_appContext);
|
||||
|
||||
try
|
||||
{
|
||||
var result = await wc.SendAsync(request, token).ConfigureAwait(false); // ConfigureAwait(false) is recommended? http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
|
||||
return result.StatusCode == HttpStatusCode.OK;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error<ScheduledTasks>(ex, "An error occurred calling web task for url: {Url}", url);
|
||||
}
|
||||
return false;
|
||||
var result = await _httpClient.SendAsync(request, token).ConfigureAwait(false); // ConfigureAwait(false) is recommended? http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
|
||||
return result.StatusCode == HttpStatusCode.OK;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error<ScheduledTasks>(ex, "An error occurred calling web task for url: {Url}", url);
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override async Task<bool> PerformRunAsync(CancellationToken token)
|
||||
@@ -93,7 +95,7 @@ namespace Umbraco.Web.Scheduling
|
||||
switch (_runtime.ServerRole)
|
||||
{
|
||||
case ServerRole.Replica:
|
||||
_logger.Debug<ScheduledTasks>("Does not run on slave servers.");
|
||||
_logger.Debug<ScheduledTasks>("Does not run on replica servers.");
|
||||
return true; // DO repeat, server role can change
|
||||
case ServerRole.Unknown:
|
||||
_logger.Debug<ScheduledTasks>("Does not run on servers with unknown role.");
|
||||
|
||||
@@ -191,7 +191,10 @@ namespace Umbraco.Web.Security
|
||||
|
||||
if (dataProtectionProvider != null)
|
||||
{
|
||||
manager.UserTokenProvider = new DataProtectorTokenProvider<T, int>(dataProtectionProvider.Create("ASP.NET Identity"));
|
||||
manager.UserTokenProvider = new DataProtectorTokenProvider<T, int>(dataProtectionProvider.Create("ASP.NET Identity"))
|
||||
{
|
||||
TokenLifespan = TimeSpan.FromDays(3)
|
||||
};
|
||||
}
|
||||
|
||||
manager.UserLockoutEnabledByDefault = true;
|
||||
@@ -703,6 +706,7 @@ namespace Umbraco.Web.Security
|
||||
var httpContext = HttpContext.Current == null ? (HttpContextBase)null : new HttpContextWrapper(HttpContext.Current);
|
||||
return httpContext.GetCurrentRequestIpAddress();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using HtmlAgilityPack;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
@@ -36,6 +38,11 @@ namespace Umbraco.Web.Templates
|
||||
{
|
||||
if (urlProvider == null) throw new ArgumentNullException("urlProvider");
|
||||
|
||||
if(string.IsNullOrEmpty(text))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
// Parse internal links
|
||||
var tags = LocalLinkPattern.Matches(text);
|
||||
foreach (Match tag in tags)
|
||||
@@ -64,6 +71,11 @@ namespace Umbraco.Web.Templates
|
||||
}
|
||||
}
|
||||
|
||||
if (UmbracoConfig.For.UmbracoSettings().Content.StripUdiAttributes)
|
||||
{
|
||||
text = StripUdiDataAttributes(text);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -75,6 +87,9 @@ namespace Umbraco.Web.Templates
|
||||
private static readonly Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
private static readonly Regex UdiDataAttributePattern = new Regex("data-udi=\"[^\\\"]*\"",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// The RegEx matches any HTML attribute values that start with a tilde (~), those that match are passed to ResolveUrl to replace the tilde with the application path.
|
||||
/// </summary>
|
||||
@@ -118,5 +133,21 @@ namespace Umbraco.Web.Templates
|
||||
{
|
||||
return text.CleanForXss(ignoreFromClean);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Strips data-udi attributes from rich text
|
||||
/// </summary>
|
||||
/// <param name="input">A html string</param>
|
||||
/// <returns>A string stripped from the data-uid attributes</returns>
|
||||
public static string StripUdiDataAttributes(string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
return UdiDataAttributePattern.Replace(input, string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ namespace Umbraco.Web.Trees
|
||||
//if the request is for folders only then just return
|
||||
if (queryStrings["foldersonly"].IsNullOrWhiteSpace() == false && queryStrings["foldersonly"] == "1") return nodes;
|
||||
|
||||
//Normal nodes
|
||||
var sysIds = GetSystemIds();
|
||||
//System ListView nodes
|
||||
var systemListViewDataTypeIds = GetNonDeletableSystemListViewDataTypeIds();
|
||||
|
||||
nodes.AddRange(
|
||||
Services.EntityService.GetChildren(intId.Result, UmbracoObjectTypes.DataType)
|
||||
@@ -56,7 +56,7 @@ namespace Umbraco.Web.Trees
|
||||
{
|
||||
var node = CreateTreeNode(dt.Id.ToInvariantString(), id, queryStrings, dt.Name, "icon-autofill", false);
|
||||
node.Path = dt.Path;
|
||||
if (sysIds.Contains(dt.Id))
|
||||
if (systemListViewDataTypeIds.Contains(dt.Id))
|
||||
{
|
||||
node.Icon = "icon-thumbnail-list";
|
||||
}
|
||||
@@ -66,15 +66,31 @@ namespace Umbraco.Web.Trees
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private IEnumerable<int> GetSystemIds()
|
||||
/// <summary>
|
||||
/// Get all integer identifiers for the non-deletable system datatypes.
|
||||
/// </summary>
|
||||
private static IEnumerable<int> GetNonDeletableSystemDataTypeIds()
|
||||
{
|
||||
var systemIds = new[]
|
||||
{
|
||||
Constants.System.DefaultLabelDataTypeId
|
||||
};
|
||||
|
||||
return systemIds.Concat(GetNonDeletableSystemListViewDataTypeIds());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all integer identifiers for the non-deletable system listviews.
|
||||
/// </summary>
|
||||
private static IEnumerable<int> GetNonDeletableSystemListViewDataTypeIds()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
Constants.DataTypes.DefaultContentListView,
|
||||
Constants.DataTypes.DefaultMediaListView,
|
||||
Constants.DataTypes.DefaultMembersListView
|
||||
|
||||
};
|
||||
return systemIds;
|
||||
}
|
||||
|
||||
protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
|
||||
@@ -87,7 +103,7 @@ namespace Umbraco.Web.Trees
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
|
||||
// root actions
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
return menu;
|
||||
}
|
||||
@@ -98,30 +114,27 @@ namespace Umbraco.Web.Trees
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
|
||||
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize(String.Format("actions/{0}", "rename")))
|
||||
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize("actions/rename"))
|
||||
{
|
||||
Icon = "icon icon-edit"
|
||||
});
|
||||
|
||||
if (container.HasChildren == false)
|
||||
{
|
||||
//can delete data type
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
}
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), hasSeparator: true);
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize($"actions/{ActionRefresh.Instance.Alias}"), hasSeparator: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sysIds = GetSystemIds();
|
||||
var nonDeletableSystemDataTypeIds = GetNonDeletableSystemDataTypeIds();
|
||||
|
||||
if (sysIds.Contains(int.Parse(id)) == false)
|
||||
{
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)));
|
||||
}
|
||||
if (nonDeletableSystemDataTypeIds.Contains(int.Parse(id)) == false)
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize(string.Format("actions/{0}", ActionMove.Instance.Alias)), hasSeparator: true);
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), hasSeparator: true);
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@ using Umbraco.Core.Logging;
|
||||
using System.Diagnostics;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Composing;
|
||||
using System.Net;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models.Packaging;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
@@ -43,6 +44,7 @@ namespace umbraco.cms.businesslogic.packager
|
||||
|
||||
private readonly List<string> _binaryFileErrors = new List<string>();
|
||||
private int _currentUserId = -1;
|
||||
private static WebClient _webClient;
|
||||
|
||||
|
||||
public string Name { get; private set; }
|
||||
@@ -684,9 +686,10 @@ namespace umbraco.cms.businesslogic.packager
|
||||
if (Directory.Exists(IOHelper.MapPath(SystemDirectories.Packages)) == false)
|
||||
Directory.CreateDirectory(IOHelper.MapPath(SystemDirectories.Packages));
|
||||
|
||||
var wc = new System.Net.WebClient();
|
||||
if (_webClient == null)
|
||||
_webClient = new WebClient();
|
||||
|
||||
wc.DownloadFile(
|
||||
_webClient.DownloadFile(
|
||||
"http://" + PackageServer + "/fetch?package=" + Package.ToString(),
|
||||
IOHelper.MapPath(SystemDirectories.Packages + "/" + Package + ".umb"));
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Umbraco.Core;
|
||||
using System.Net.Http;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Mime;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Xml;
|
||||
@@ -16,42 +16,45 @@ namespace dashboardUtilities
|
||||
|
||||
public partial class FeedProxy : UmbracoEnsuredPage
|
||||
{
|
||||
private static HttpClient _httpClient;
|
||||
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Request.QueryString.AllKeys.Contains("url") && Request.QueryString["url"] != null)
|
||||
{
|
||||
var url = Request.QueryString["url"];
|
||||
if (!string.IsNullOrWhiteSpace(url) && !url.StartsWith("/"))
|
||||
{
|
||||
Uri requestUri;
|
||||
if (Uri.TryCreate(url, UriKind.Absolute, out requestUri))
|
||||
{
|
||||
var feedProxyXml = XmlHelper.OpenAsXmlDocument(IOHelper.MapPath(SystemFiles.FeedProxyConfig));
|
||||
if (feedProxyXml != null
|
||||
&& feedProxyXml.SelectSingleNode(string.Concat("//allow[@host = '", requestUri.Host, "']")) != null
|
||||
&& requestUri.Port == 80)
|
||||
{
|
||||
using (var client = new WebClient())
|
||||
{
|
||||
var response = client.DownloadString(requestUri);
|
||||
if (Request.QueryString.AllKeys.Contains("url") == false || Request.QueryString["url"] == null)
|
||||
return;
|
||||
|
||||
if (string.IsNullOrEmpty(response) == false)
|
||||
{
|
||||
Response.Clear();
|
||||
Response.ContentType = Request.CleanForXss("type") ?? MediaTypeNames.Text.Xml;
|
||||
Response.Write(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Current.Logger.Debug<FeedProxy>("Access to unallowed feedproxy attempted: {RequestUrl}", requestUri);
|
||||
}
|
||||
}
|
||||
var url = Request.QueryString["url"];
|
||||
if (string.IsNullOrWhiteSpace(url) || url.StartsWith("/"))
|
||||
return;
|
||||
|
||||
if (Uri.TryCreate(url, UriKind.Absolute, out var requestUri) == false)
|
||||
return;
|
||||
|
||||
var feedProxyXml = XmlHelper.OpenAsXmlDocument(IOHelper.MapPath(SystemFiles.FeedProxyConfig));
|
||||
if (feedProxyXml?.SelectSingleNode($"//allow[@host = '{requestUri.Host}']") != null && requestUri.Port == 80)
|
||||
{
|
||||
if (_httpClient == null)
|
||||
_httpClient = new HttpClient();
|
||||
|
||||
using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
|
||||
{
|
||||
var response = _httpClient.SendAsync(request).Result;
|
||||
var result = response.Content.ReadAsStringAsync().Result;
|
||||
|
||||
if (string.IsNullOrEmpty(result))
|
||||
return;
|
||||
|
||||
Response.Clear();
|
||||
Response.ContentType = Request.CleanForXss("type") ?? MediaTypeNames.Text.Xml;
|
||||
Response.Write(result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Current.Logger.Debug<FeedProxy>("Access to unallowed feedproxy attempted: {RequestUrl}", requestUri);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user