protected override DriverResult Editor(ContentPart part, Fields.SecureFileField field, IUpdateModel updater, dynamic shapeHelper) { WorkContext wc = _workContextAccessor.GetContext(); var file = wc.HttpContext.Request.Files["FileField-" + field.Name]; // if the model could not be bound, don't try to validate its properties if (updater.TryUpdateModel(field, GetPrefix(field, part), null, null)) { var settings = field.PartFieldDefinition.Settings.GetModel <SecureFileFieldSettings>(); var extensions = String.IsNullOrWhiteSpace(settings.AllowedExtensions) ? new string[0] : settings.AllowedExtensions.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); try { if (file != null && file.ContentLength > 0) { string fname = Path.GetFileName(file.FileName); field.Url = fname; IStorageProvider provider; provider = new SecureFileStorageProvider(settings.SecureDirectoryName); int length = (int)file.ContentLength; byte[] buffer = new byte[length]; using (Stream stream = file.InputStream) { stream.Read(buffer, 0, length); } provider.Insert(fname, buffer, file.ContentType, length, true); } } catch (Exception) { throw; } if (extensions.Any() && field.Url != null && !extensions.Any(x => field.Url.EndsWith(x, StringComparison.OrdinalIgnoreCase))) { updater.AddModelError("Url", T("The field {0} must have one of these extensions: {1}", field.Name.CamelFriendly(), settings.AllowedExtensions)); } if (settings.Required && String.IsNullOrWhiteSpace(field.Url)) { updater.AddModelError("Url", T("The field {0} is mandatory", field.Name.CamelFriendly())); } } return(Editor(part, field, shapeHelper)); }
public ActionResult GetSecureFile(int id, string fieldName) { var accessGranted = false; WorkContext wc = _services.WorkContext; IUser user = _services.WorkContext.CurrentUser; if (!String.IsNullOrEmpty(wc.CurrentSite.SuperUser) && user != null && String.Equals(user.UserName, wc.CurrentSite.SuperUser, StringComparison.Ordinal)) { accessGranted = true; } var content = _services.ContentManager.Get <ContentPart>(id); if (content == null) { return(RedirectToAction("NotFound")); } var part = content.ContentItem.As <ContentPermissionsPart>(); // if the content item has no right attached, check on the container if (part == null || !part.Enabled) { var commonPart = part.As <CommonPart>(); if (commonPart != null && commonPart.Container != null) { part = commonPart.As <ContentPermissionsPart>(); } } //if we do not have access level permissions for this content item then we need to check if user can view the content if (part == null || !part.Enabled) { accessGranted = _authorizationService.TryCheckAccess(Permissions.ViewContent, user, content); } else { var hasOwnership = HasOwnership(user, content.ContentItem); IEnumerable <string> authorizedRoles; //we only care about view permission in this field authorizedRoles = (hasOwnership ? part.ViewOwnContent : part.ViewContent).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); // determine what set of roles should be examined by the access check IEnumerable <string> rolesToExamine; if (user == null) { rolesToExamine = AnonymousRole; } else if (user.Has <IUserRoles>()) { // the current user is not null, so get his roles and add "Authenticated" to it rolesToExamine = user.As <IUserRoles>().Roles; // when it is a simulated anonymous user in the admin if (!rolesToExamine.Contains(AnonymousRole[0])) { rolesToExamine = rolesToExamine.Concat(AuthenticatedRole); } } else { // the user is not null and has no specific role, then it's just "Authenticated" rolesToExamine = AuthenticatedRole; } accessGranted = rolesToExamine.Any(x => authorizedRoles.Contains(x, StringComparer.OrdinalIgnoreCase)); } if (accessGranted) { var field = (Fields.SecureFileField)(content.ContentItem).Parts.SelectMany(p => p.Fields).First(f => f.Name == fieldName); var settings = field.PartFieldDefinition.Settings.GetModel <SecureFileFieldSettings>(); IStorageProvider provider; if (!string.IsNullOrEmpty(settings.SecureBlobAccountName)) { provider = new SecureAzureBlobStorageProvider(settings.SecureBlobAccountName, settings.SecureSharedKey, settings.SecureBlobEndpoint, true, settings.SecureDirectoryName); } else { // I need to check if, by setting, the file is in a subfolder. string repo = settings.SecureDirectoryName; if (!string.IsNullOrWhiteSpace(field.Subfolder)) { repo = Path.Combine(repo, field.Subfolder); } provider = new SecureFileStorageProvider(repo); } if (!provider.Exists(field.Url)) { return(RedirectToAction("NotFound")); } IStorageFile file = provider.Get <StorageFile>(field.Url); Stream fs = new MemoryStream(file.FileBytes); if (settings.EncryptFile) { byte[] fileBytes = new byte[fs.Length]; fs.Read(fileBytes, 0, (int)fs.Length); fileBytes = _encryptionService.Decode(fileBytes); fs = new MemoryStream(fileBytes); } string mimeType = MimeMapping.GetMimeMapping(file.FileName); return(new FileStreamResult(fs, mimeType)); } return(RedirectToAction("NotFound")); }
protected override DriverResult Editor(ContentPart part, Fields.SecureFileField field, IUpdateModel updater, dynamic shapeHelper) { WorkContext wc = _workContextAccessor.GetContext(); var file = wc.HttpContext.Request.Files["FileField-" + field.Name]; // if the model could not be bound, don't try to validate its properties if (updater.TryUpdateModel(field, GetPrefix(field, part), null, null)) { var settings = field.PartFieldDefinition.Settings.GetModel <SecureFileFieldSettings>(); var extensions = String.IsNullOrWhiteSpace(settings.AllowedExtensions) ? new string[0] : settings.AllowedExtensions.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); try { if (file != null && file.ContentLength > 0) { string fname = Path.GetFileName(file.FileName); if (settings.GenerateFileName) { var extension = Path.GetExtension(file.FileName); fname = Guid.NewGuid().ToString("n") + extension; } if (extensions.Any() && fname != null && !extensions.Any(x => fname.EndsWith(x, StringComparison.OrdinalIgnoreCase))) { updater.AddModelError("Url", T("The field {0} must have one of these extensions: {1}", field.DisplayName.CamelFriendly(), settings.AllowedExtensions)); return(Editor(part, field, shapeHelper)); } if (settings.Required && String.IsNullOrWhiteSpace(fname)) { updater.AddModelError("Url", T("The field {0} is mandatory", field.DisplayName.CamelFriendly())); return(Editor(part, field, shapeHelper)); } DateTime upload = DateTime.UtcNow; field.Upload = upload; field.Url = fname; IStorageProvider provider; if (!string.IsNullOrEmpty(settings.SecureBlobAccountName)) { provider = new SecureAzureBlobStorageProvider(settings.SecureBlobAccountName, settings.SecureSharedKey, settings.SecureBlobEndpoint, true, settings.SecureDirectoryName); } else { string url = settings.SecureDirectoryName; string subfolder = _tokenizer.Replace(settings.CustomSubfolder, new Dictionary <string, object> { { "Content", part.ContentItem } }); if (!string.IsNullOrWhiteSpace(subfolder)) { field.Subfolder = subfolder; url = Path.Combine(url, subfolder); if (!Directory.Exists(url)) { Directory.CreateDirectory(url); } } provider = new SecureFileStorageProvider(url); } int length = (int)file.ContentLength; byte[] buffer = new byte[length]; using (Stream stream = file.InputStream) { stream.Read(buffer, 0, length); } if (settings.EncryptFile) { buffer = _encryptionService.Encode(buffer); } provider.Insert(fname, buffer, file.ContentType, length, true); } } catch (Exception) { throw; } } return(Editor(part, field, shapeHelper)); }
/// <summary> /// Endpoint to retrieve a secured file. Content Item permissions are inherited from the parent content item. /// </summary> /// <param name="id">Unique Id on Parent Content Item</param> /// <param name="fieldName">Unique Field Name for the file field.</param> /// <returns></returns> public ActionResult GetSecureFile(int id, string fieldName) { var accessGranted = false; WorkContext wc = _services.WorkContext; IUser user = _services.WorkContext.CurrentUser; if (!String.IsNullOrEmpty(wc.CurrentSite.SuperUser) && user != null && String.Equals(user.UserName, wc.CurrentSite.SuperUser, StringComparison.Ordinal)) { accessGranted = true; } var content = _services.ContentManager.Get <ContentPart>(id); if (content == null) { return(null); } var part = content.ContentItem.As <ContentPermissionsPart>(); // if the content item has no right attached, check on the container if (part == null || !part.Enabled) { var commonPart = part.As <CommonPart>(); if (commonPart != null && commonPart.Container != null) { part = commonPart.As <ContentPermissionsPart>(); } } //if we do not have access level permissions for this content item then we need to give access if (part == null || !part.Enabled) { accessGranted = true; } else { var hasOwnership = HasOwnership(user, content.ContentItem); IEnumerable <string> authorizedRoles; //we only care about view permission in this field authorizedRoles = (hasOwnership ? part.ViewOwnContent : part.ViewContent).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); // determine what set of roles should be examined by the access check IEnumerable <string> rolesToExamine; if (user == null) { rolesToExamine = AnonymousRole; } else if (user.Has <IUserRoles>()) { // the current user is not null, so get his roles and add "Authenticated" to it rolesToExamine = user.As <IUserRoles>().Roles; // when it is a simulated anonymous user in the admin if (!rolesToExamine.Contains(AnonymousRole[0])) { rolesToExamine = rolesToExamine.Concat(AuthenticatedRole); } } else { // the user is not null and has no specific role, then it's just "Authenticated" rolesToExamine = AuthenticatedRole; } accessGranted = rolesToExamine.Any(x => authorizedRoles.Contains(x, StringComparer.OrdinalIgnoreCase)); } if (accessGranted) { var field = (Fields.SecureFileField)(content.ContentItem).Parts.SelectMany(p => p.Fields).First(f => f.Name == fieldName); var settings = field.PartFieldDefinition.Settings.GetModel <SecureFileFieldSettings>(); IStorageProvider provider; provider = new SecureFileStorageProvider(settings.SecureDirectoryName); IStorageFile file = provider.Get <StorageFile>(field.Url); Stream fs = new MemoryStream(file.FileBytes); return(new FileStreamResult(fs, file.ContentType) { FileDownloadName = file.FileName }); } return(new HttpUnauthorizedResult()); }