internal Dictionary <string, object> CreateOrUpdate(IInstanceContext context, IBlock ctxBlock, string contentType, Dictionary <string, object> newContentItem, int?id = null, string appPath = null) { Log.Add($"create or update type:{contentType}, id:{id}, path:{appPath}"); // if app-path specified, use that app, otherwise use from context var appIdentity = AppFinder.GetAppIdFromPathOrContext(appPath, ctxBlock); // Check that this ID is actually of this content-type, // this throws an error if it's not the correct type var itm = id == null ? null : new EntityApi(appIdentity.AppId, true, Log).GetOrThrow(contentType, id.Value); var ok = itm == null ? new MultiPermissionsTypes() .Init(context, GetApp(appIdentity.AppId, ctxBlock), contentType, Log) .EnsureAll(Grants.Create.AsSet(), out var error) : new MultiPermissionsItems().Init(context, GetApp(appIdentity.AppId, ctxBlock), itm, Log) .EnsureAll(Grants.Update.AsSet(), out error); if (!ok) { throw HttpException.PermissionDenied(error); } // Convert to case-insensitive dictionary just to be safe! newContentItem = new Dictionary <string, object>(newContentItem, StringComparer.OrdinalIgnoreCase); // Now create the cleaned up import-dictionary so we can create a new entity var cleanedNewItem = new AppContentEntityBuilder(Log) .CreateEntityDictionary(contentType, newContentItem, appIdentity.AppId); var userName = context.User.IdentityToken; // try to create // 2020-08-21 disabled publish check, don't think it's relevant in API mode // var publish = Factory.Resolve<IPagePublishing>().Init(Log); // var enablePublish = publish.IsEnabled(context.Container.Id); var currentApp = GetApp(appIdentity.AppId, ctxBlock); //Factory.Resolve<Apps.App>().Init(appIdentity, // ConfigurationProvider.Build(false, false, // ctxBlockBuilder?.Block.Data.Configuration.LookUps), true, Log); if (id == null) { var entity = currentApp.Data.Create(contentType, cleanedNewItem, userName); id = entity.EntityId; } else { currentApp.Data.Update(id.Value, cleanedNewItem, userName); } return(InitEavAndSerializer(appIdentity.AppId, ctxBlock?.EditAllowed ?? false) .Convert(currentApp.Data.List.One(id.Value))); }
[AllowAnonymous] // will check security internally, so assume no requirements public Dictionary <string, object> CreateOrUpdate([FromUri] string contentType, [FromBody] Dictionary <string, object> newContentItem, [FromUri] int?id = null, [FromUri] string appPath = null) { Log.Add($"create or update type:{contentType}, id:{id}, path:{appPath}"); // if app-path specified, use that app, otherwise use from context var appIdentity = AppFinder.GetAppIdFromPathOrContext(appPath, BlockBuilder); // Check that this ID is actually of this content-type, // this throws an error if it's not the correct type var itm = id == null ? null : new EntityApi(appIdentity.AppId, true, Log).GetOrThrow(contentType, id.Value); var ok = itm == null ? new MultiPermissionsTypes(BlockBuilder, appIdentity.AppId, contentType, Log) .EnsureAll(Grants.Create.AsSet(), out var exp) : new MultiPermissionsItems(BlockBuilder, appIdentity.AppId, itm, Log) .EnsureAll(Grants.Update.AsSet(), out exp); if (!ok) { throw exp; } //2018-09-15 2dm moved/disabled //var context = GetContext(SxcBlock, Log); //PerformSecurityCheck(appIdentity, contentType, perm, appPath == null ? context.Dnn.Module : null, itm); // Convert to case-insensitive dictionary just to be safe! newContentItem = new Dictionary <string, object>(newContentItem, StringComparer.OrdinalIgnoreCase); // Now create the cleaned up import-dictionary so we can create a new entity var cleanedNewItem = new AppContentEntityBuilder(Log) .CreateEntityDictionary(contentType, newContentItem, appIdentity.AppId); var userName = new DnnUser().IdentityToken; // try to create var publish = Factory.Resolve <IEnvironmentFactory>().PagePublisher(Log); // 2018-09-22 new // todo: something looks wrong here, I think create/update would fail if it doesn't have a moduleid var currentApp = new Apps.App(new DnnTenant(PortalSettings), appIdentity.ZoneId, appIdentity.AppId, ConfigurationProvider.Build(false, publish.IsEnabled(ActiveModule.ModuleID), BlockBuilder.Block.Data.Configuration.LookUps), true, Log); if (id == null) { currentApp.Data.Create(contentType, cleanedNewItem, userName); // Todo: try to return the newly created object return(null); } currentApp.Data.Update(id.Value, cleanedNewItem, userName); return(InitEavAndSerializer(appIdentity.AppId).Convert(currentApp.Data.List.One(id.Value))); }
public Dictionary <string, object> CreateOrUpdate(string contentType, Dictionary <string, object> newContentItem, int?id = null, string appPath = null) { Log.Add($"create or update type:{contentType}, id:{id}, path:{appPath}"); // if app-path specified, use that app, otherwise use from context // Check that this ID is actually of this content-type, // this throws an error if it's not the correct type var itm = id == null ? null : Context.AppState.List.GetOrThrow(contentType, id.Value); if (itm == null) { ThrowIfNotAllowedInType(contentType, Grants.Create.AsSet(), Context.AppState); } else { ThrowIfNotAllowedInItem(itm, Grants.Update.AsSet(), Context.AppState); } // Convert to case-insensitive dictionary just to be safe! newContentItem = new Dictionary <string, object>(newContentItem, StringComparer.OrdinalIgnoreCase); // Now create the cleaned up import-dictionary so we can create a new entity var cleanedNewItem = new AppContentEntityBuilder(Log) .CreateEntityDictionary(contentType, newContentItem, Context.AppState.AppId); var userName = Context.User.IdentityToken; var realApp = GetApp(Context.AppState.AppId, Context.UserMayEdit); if (id == null) { var entity = realApp.Data.Create(contentType, cleanedNewItem, userName); id = entity.EntityId; } else { realApp.Data.Update(id.Value, cleanedNewItem, userName); } return(InitEavAndSerializer(Context.AppState.AppId, Context.UserMayEdit) .Convert(realApp.Data.List.One(id.Value))); }