public DialogContextStandalone DialogSettings(int appId) { // reset app-id if we get a info-token like -100 if (appId < 0) { appId = Eav.Constants.AppIdEmpty; } var appContext = appId != Eav.Constants.AppIdEmpty ? _ctxResolver.App(appId) : null; var context = appContext ?? _ctxResolver.Site(); // if we have an appid (we don't have it in an install-new-apps-scenario) check permissions if (appContext != null) { var appAndPerms = ServiceProvider.Build <MultiPermissionsApp>().Init(appContext, appContext.AppState, Log); if (!appAndPerms.ZoneIsOfCurrentContextOrUserIsSuper(out var error)) { throw HttpException.PermissionDenied(error); } } var cb = _uiContextBuilder.SetZoneAndApp(context.Site.ZoneId, appContext?.AppState); return(new DialogContextStandalone { Context = cb.Get(Ctx.All), }); }
public IEnumerable <ViewDto> ViewUsage(int appId, Guid guid, Func <List <IView>, List <BlockConfiguration>, IEnumerable <ViewDto> > finalBuilder) { var wrapLog = Log.Call <IEnumerable <ViewDto> >($"{appId}, {guid}"); var context = _ctxResolver.App(appId); // extra security to only allow zone change if host user var permCheck = ServiceProvider.Build <MultiPermissionsApp>().Init(context, context.AppState, Log); if (!permCheck.EnsureAll(GrantSets.ReadSomething, out var error)) { throw HttpException.PermissionDenied(error); } var cms = _cmsRuntime.Init(context.AppState, context.UserMayEdit, Log); // treat view as a list - in case future code will want to analyze many views together var views = new List <IView> { cms.Views.Get(guid) }; var blocks = cms.Blocks.AllWithView(); Log.Add($"Found {blocks.Count} content blocks"); var result = finalBuilder(views, blocks); return(wrapLog("ok", result)); }
public EditSaveBackend Init(int appId, ILog log) { Init(log); _appId = appId; // The context should be from the block if there is one, because it affects saving/publishing // Basically it can result in things being saved draft or titles being updated _context = _ctxResolver.BlockOrNull() ?? _ctxResolver.App(appId); // context; _pagePublishing.Init(_context, Log); return(this); }
public T Init(int appId, string contentType, Guid itemGuid, string field, bool usePortalRoot, ILog parentLog) { Log.LinkTo(parentLog); var context = appId > 0 ? _ctxResolver.App(appId) : _ctxResolver.AppNameRouteBlock(null); var logCall = Log.Call <T>($"app: {context.AppState.Show()}, type: {contentType}, itemGuid: {itemGuid}, field: {field}, portalRoot: {usePortalRoot}"); State.Init(context, contentType, field, itemGuid, usePortalRoot, Log); return(logCall(null, this as T)); }
public string ResolveHyperlink(int appId, string hyperlink, string contentType, Guid guid, string field) { try { var context = _ctxResolver.App(appId); // different security checks depending on the link-type var lookupPage = hyperlink.Trim().StartsWith("page", StringComparison.OrdinalIgnoreCase); // look it up first, because we need to know if the result is in ADAM or not (different security scenario) var conv = ServiceProvider.Build <IValueConverter>(); var resolved = conv.ToValue(hyperlink, guid); if (lookupPage) { // page link - only resolve if the user has edit-permissions // only people who have some full edit permissions may actually look up pages var permCheckPage = ServiceProvider.Build <MultiPermissionsApp>().Init(context, context.AppState, Log); return(permCheckPage.UserMayOnAll(GrantSets.WritePublished) ? resolved : hyperlink); } // for file, we need guid & field - otherwise return the original unmodified if (guid == default || string.IsNullOrEmpty(field) || string.IsNullOrEmpty(contentType)) { return(hyperlink); } var isOutsideOfAdam = !(resolved.IndexOf($"/{AdamConstants.AdamRootFolder}/", StringComparison.Ordinal) > 0); // file-check, more abilities to allow // this will already do a ensure-or-throw inside it if outside of adam var adamCheck = AdamState; // new AdamState<int, int>(); adamCheck.Init(context, contentType, field, guid, isOutsideOfAdam, Log); if (!adamCheck.Security.SuperUserOrAccessingItemFolder(resolved, out var exp)) { throw exp; } if (!adamCheck.Security.UserIsPermittedOnField(GrantSets.ReadSomething, out exp)) { throw exp; } // if everything worked till now, it's ok to return the result return(resolved); } catch { return(hyperlink); } }
public override XmlExporter Init(int zoneId, int appId, AppRuntime appRuntime, bool appExport, string[] attrSetIds, string[] entityIds, ILog parentLog) { var context = _ctxResolver.App(appId); var tenant = new DnnSite(); var app = AdamManager.AppRuntime.ServiceProvider.Build <App>().InitNoData(new AppIdentity(zoneId, appId), Log); AdamManager.Init(context, 10, Log); Constructor(zoneId, appRuntime, app.AppGuid, appExport, attrSetIds, entityIds, parentLog); // this must happen very early, to ensure that the file-lists etc. are correct for exporting when used externally InitExportXDocument(tenant.DefaultCultureCode, Settings.ModuleVersion); return(this); }
internal Dictionary <string, IEnumerable <Dictionary <string, object> > > Query(int?appId, string name, bool includeGuid, string stream) { var wrapLog = Log.Call($"'{name}', inclGuid: {includeGuid}, stream: {stream}"); var appCtx = appId != null?_ctxResolver.App(appId.Value) : _ctxResolver.BlockRequired(); // If no app available from context, check if an app-id was supplied in url // Note that it may only be an app from the current portal // and security checks will run internally var app = ServiceProvider.Build <Apps.App>().Init(ServiceProvider, appCtx.AppState.AppId, Log, appCtx.UserMayEdit); var result = BuildQueryAndRun(app, name, stream, includeGuid, appCtx, Log, appCtx.UserMayEdit); wrapLog(null); return(result); }
// New feature in 11.03 - Usage Statistics public dynamic Usage(int appId, Guid guid) { var context = _ctxResolver.App(appId); var permCheck = ServiceProvider.Build <MultiPermissionsApp>().Init(context, context.AppState, Log); if (!permCheck.EnsureAll(GrantSets.ReadSomething, out var error)) { throw HttpException.PermissionDenied(error); } var item = context.AppState.List.One(guid); var relationships = item.Relationships.AllRelationships; // var result = relationships.Select(r => new EntityInRelationDto(r.)) // todo: don't forget Metadata relationships return(null); }
public IEnumerable <EntityForPickerDto> GetAvailableEntities(int appId, string[] items, string contentTypeName) { var context = _ctxResolver.App(appId); // do security check var permCheck = string.IsNullOrEmpty(contentTypeName) ? ServiceProvider.Build <MultiPermissionsApp>().Init(context, context.AppState, Log) : ServiceProvider.Build <MultiPermissionsTypes>().Init(context, context.AppState, contentTypeName, Log); if (!permCheck.EnsureAll(GrantSets.ReadSomething, out var error)) { throw HttpException.PermissionDenied(error); } // maybe in the future, ATM not relevant var withDrafts = permCheck.EnsureAny(GrantSets.ReadDraft); return(_entityPickerApi.Init(Log).GetAvailableEntities(appId, items, contentTypeName, withDrafts)); }
public EditDto Load(int appId, List <ItemIdentifier> items) { // Security check var wrapLog = Log.Call($"load many a#{appId}, items⋮{items.Count}"); var context = _ctxResolver.App(appId); var showDrafts = context.UserMayEdit; // do early permission check - but at this time it may be that we don't have the types yet // because they may be group/id combinations, without type information which we'll look up afterwards var appIdentity = State.Identity(null, appId); items = _contentGroupList.Init(appIdentity, Log, showDrafts).ConvertListIndexToId(items); TryToAutoFindMetadataSingleton(items, context.AppState); // now look up the types, and repeat security check with type-names // todo: 2020-03-20 new feat 11.01, may not check inner type permissions ATM var permCheck = ServiceProvider.Build <MultiPermissionsTypes>().Init(context, context.AppState, items, Log); if (!permCheck.EnsureAll(GrantSets.WriteSomething, out var error)) { throw HttpException.PermissionDenied(error); } // load items - similar var result = new EditDto(); var entityApi = _entityApi.Init(appId, permCheck.EnsureAny(GrantSets.ReadDraft), Log); var typeRead = entityApi.AppRead.ContentTypes; var list = entityApi.GetEntitiesForEditing(items); var jsonSerializer = ServiceProvider.Build <JsonSerializer>(); result.Items = list.Select(e => new BundleWithHeader <JsonEntity> { Header = e.Header, Entity = GetSerializeAndMdAssignJsonEntity(appId, e, jsonSerializer, typeRead) }).ToList(); // set published if some data already exists if (list.Any()) { result.IsPublished = list.First().Entity?.IsPublished ?? true; // Entity could be null (new), then true // only set draft-should-branch if this draft already has a published item if (!result.IsPublished) { result.DraftShouldBranch = list.First().Entity?.GetPublished() != null; } } // since we're retrieving data - make sure we're allowed to // this is to ensure that if public forms only have create permissions, they can't access existing data // important, this code is shared/duplicated in the EntitiesController.GetManyForEditing if (list.Any(set => set.Entity != null)) { if (!permCheck.EnsureAll(GrantSets.ReadSomething, out error)) { throw HttpException.PermissionDenied(error); } } // load content-types var types = UsedTypes(list, typeRead); result.ContentTypes = types .Select(ct => JsonSerializer.ToJson(ct, true)) .ToList(); //// TEMP DEBUG //var inputTypes = types.SelectMany(t => t.Attributes.Select(a => //{ // var Lookup = a.InputType(); // var mdAll = a.Metadata.Where(md => md.Type.Is(Constants.MetadataFieldTypeAll)).ToList(); // var MdAllCount = mdAll.Count; // var MdAllAttribCount = mdAll.FirstOrDefault()?.Attributes.Count; // var MdAllWithAttrib = mdAll.FirstOrDefault(md => md.Attributes.ContainsKey(Constants.MetadataFieldTypeAll)); // var MdAllAttrib = MdAllWithAttrib?.GetBestValue<string>(Constants.MetadataFieldTypeAll); // var MdAllAttribZero = MdAllWithAttrib?.GetBestValue<string>(Constants.MetadataFieldTypeAll, new string[0]); // var MdAllAttribEmpty = MdAllWithAttrib?.GetBestValue<string>(Constants.MetadataFieldTypeAll, new []{""}); // var MdAllAttribEn = MdAllWithAttrib?.GetBestValue<string>(Constants.MetadataFieldTypeAll, new[] { "en-us" }); // var MdAllAttribTr = MdAllWithAttrib?.GetBestValue<string>(Constants.MetadataFieldTypeAll, new[] { "tr-tr" }); // var MdAllType = a.Metadata.GetBestValue<string>(Constants.MetadataFieldAllInputType, Constants.MetadataFieldTypeAll); // return new {Lookup, MdAllCount, MdAllType, MdAllAttribCount, MdAllWithAttrib?.EntityId, MdAllAttrib, MdAllAttribZero, MdAllAttribEmpty, MdAllAttribEn, MdAllAttribTr }; //})); //var serializedDebug = JsonConvert.SerializeObject(inputTypes); //Log.Add("Test / debug: " + serializedDebug); // ensure that sub-properties of the content-types are included // this is for UI Formulas (children of @All) - WIP // and the warning/error Regex specials - WIP var entList = types.SelectMany( // in all Content-Type attributes like title, body etc. t => t.Attributes.SelectMany( // check all metadata of these attributes - get possible sub-entities attached a => a.Metadata.SelectMany(m => m.Children()) ) ); result.ContentTypeItems = entList.Select(e => jsonSerializer.ToJson(e, 0, Log)).ToList(); // Fix not-supported input-type names; map to correct name result.ContentTypes .ForEach(jt => jt.Attributes .ForEach(at => at.InputType = InputTypes.MapInputTypeV10(at.InputType))); // load input-field configurations result.InputTypes = GetNecessaryInputTypes(result.ContentTypes, typeRead); // also include UI features result.Features = FeaturesHelpers.FeatureListWithPermissionCheck(permCheck).ToList(); // Attach context, but only the minimum needed for the UI result.Context = _contextBuilder.SetZoneAndApp(appIdentity.ZoneId, context.AppState) .Get(Ctx.AppBasic | Ctx.Language | Ctx.Site | Ctx.System); try { result.Prefetch = TryToPrefectAdditionalData(appId, result); } catch (Exception) { /* ignore */ } // done - return wrapLog($"ready, sending items:{result.Items.Count}, " + $"types:{result.ContentTypes.Count}, " + $"inputs:{result.InputTypes.Count}, " + $"feats:{result.Features.Count}"); return(result); }