Compare commits

...
Author SHA1 Message Date
Andreas ZerbstandGitHub f98599a431 Changed locator (#15714) 2024-02-14 14:08:42 +01:00
Jacob Overgaard b8d6c3e4fa update backoffice submodule 2024-02-14 13:10:06 +01:00
2dcdff5392 V14: Migrate nucache to use System.Text.Json (#15685)
* Create system text serializer

* Assign property names with system text

* Use the new serializer

* Impement AutoInterningStringConverter with System.Text.Json

* Implement TextAutoInterningStringKeyCaseInsensitiveDictionaryConverter

* Make CaseInsensitiveDictionaryConverter

* Force datetimes to be read as UTC

* Remove usages of Newtonsoft.Json

* Remove text prefixes

* Remove unused Newtonsoft converter

* Remove more newtonsoft

* Remove duplicate implementation

* Rmove usage of missing class in tests

* Ignore null values

* Fix tests

* Remove Newtonstoft reference from NuCache

---------

Co-authored-by: Elitsa <elm@umbraco.dk>
2024-02-14 12:10:45 +01:00
Kenn JacobsenandGitHub 4f04669dce Enable reuse of BackOfficeSecurityRequirementsOperationFilter for custom APIs (#15699) 2024-02-13 15:08:42 +01:00
Andreas ZerbstandGitHub 690bfe3e68 V14 QA fix failing dictionary acceptance tests. (#15709)
* Updated test to work. And skips tests unable to work until frontend is ready

* Decreased time for tests

* Update playwright.config.ts

Decreased to 40 seconds
2024-02-13 13:28:28 +01:00
Jacob Overgaard 7577433cd5 update backoffice submodule 2024-02-13 12:18:09 +01:00
Andreas ZerbstandGitHub f92c23438e Decreased retry of test from 5 to 3. (#15705) 2024-02-13 09:04:50 +01:00
Jacob Overgaard c27532fe72 update backoffice submodule 2024-02-12 15:33:50 +01:00
d057626f29 V14 Added acceptance tests for DataTypes (#15679)
* Fixed failing tests

* Updated tests to use the updated helpers

* Clean up tests

* Enabled our pipeline for E2E testing

* Updated the CMS URl for our E2E tests

* Bumped version of our testHelpers

* Did some fixing, still a bit more to do

* Updated auth tests to use LoginUiHelper

* Updated Telemetry tests to use TelemetryUiHelper

* Updated LogViewer tests to use LogViewerUiHelper

* Updated api tests to apply AAA pattern and fix failed tests

* Removed unused import

* Fixed comments

* Bumped version of test helper

* Updated the version to 10 instead of 11

* Updated the package-lock.json file to contain the correct versions

* Added a waitForTimeout
The reason for this is that this test is failing on the pipeline

* V14 Added acceptance test for basic functions of Data Type, Approved Color and Label (#15551)

* Updated api tests for DataType

* Added ui tests for basic functions of DataType

* Added ui tests for Approved color

* Added ui tests for Label

* Fixed comments

* V14 Added acceptance tests for Date Picker (#15561)

* Updated api tests for DataType

* Added ui tests for basic functions of DataType

* Added ui tests for Approved color

* Added ui tests for Label

* Added ui tests for Date Picker

* Removed blank line

Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>

---------

Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>

* V14 Added acceptance test for List View (#15575)

* Updated api tests for DataType

* Added ui tests for basic functions of DataType

* Added ui tests for Approved color

* Added ui tests for Label

* Added ui tests for Date Picker

* Fix merged

* Updated DatePicker and Label tests to apply best practices

* Added ui tests for ListView

* V14 Added acceptance tests for Image Cropper, Numeric and Radiobox (#15599)

* Added ui tests for ImageCropper

* Added ui tests for Numeric

* Added ui tests for Radiobox

* Updated tests for Approved Color to change the way to arrange test data

* Change "" to '' and updated before/after methods

* V14 Added acceptance test for Textarea, Textstring, Upload (#15606)

* Added ui tests for Textarea

* Added ui tests for Textstring

* Added ui tests for Upload Article, Upload Audio, Upload File, Upload Vector Graphics, Upload Video

* Fixed failing tests due to api changes

* Changed propertyEditorAlias to editorAlias due to api changes

* Removed the step to check notification displays and changed string variables to numeric variables due to api changes

* Updated the skip tests

* Added skip tests and update method name due to test helper changes

* Splited tests out

* Bumped version

* Changed '' to '

---------

Co-authored-by: Andreas Zerbst <andr317c@live.dk>
Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>
2024-02-12 13:59:39 +01:00
Jacob Overgaard 629f854bf7 update backoffice submodule 2024-02-12 11:06:10 +01:00
Jacob Overgaard 6f6405a445 update backoffice submodule 2024-02-12 09:31:39 +01:00
Jacob Overgaard 21dc62ec22 update backoffice submodule 2024-02-09 15:43:54 +01:00
Jacob Overgaard afff4d7578 update backoffice submodule 2024-02-09 13:55:40 +01:00
Jacob Overgaard 10e328afda Merge branch 'release/14.0' into v14/dev 2024-02-07 14:33:19 +01:00
Jacob Overgaard 86bf666faf fix useDotNet job 2024-02-07 14:31:16 +01:00
Jacob Overgaard b67b06bfc3 bump version to 14.0.0--preview006 2024-02-07 13:47:36 +01:00
Jacob Overgaard da5a95ac22 Merge remote-tracking branch 'origin/v14/dev' into v14/dev 2024-02-07 12:08:03 +01:00
Jacob Overgaard fdb9b68bc0 update backoffice submodule 2024-02-07 12:07:41 +01:00
024bb8903c V14/feature/delete media in recyblebin (#15636)
* Bugfix: MediaCacheRefresher needs to always clear the mediaCache no matter what the publishedState is

* fix: check correct permissions for deleteDocumentFromRecycleBin

* Fix: ImageCropper propertyValues should not hold invalid values.

* Added media delete endpoints

* PR comment fix: Do not schedule cleanup if we know the file does not exist.

* resolved forward merge build conflicts

namespace cleanup

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
2024-02-07 10:44:20 +01:00
Kenn JacobsenandGitHub 9d07268ead Remove template scaffolding from the API (#15659)
* Remove template scaffolding from the API

* Regenerate OpenApi.json

* Regenerate OpenApi.json after forward merging
2024-02-07 09:07:54 +01:00
Jacob Overgaard 79866e0370 update backoffice submodule 2024-02-07 09:01:01 +01:00
Bjarke Berg c1aa526999 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2024-02-06 14:25:12 +01:00
183b5cc454 Management API model mapping take two (#15667)
* Re-modelling API models (take two)

* Do not use "content" - use "document" and "media" instead.

* Move "item" endpoints to their own silo

* Use "Id", not "Key"

* Regenerate OpenApi.json

* Rename user start node IDs from "content" to "document"

* Regererate OpenApi.json after forward merge

* update importmap

---------

Co-authored-by: Mads Rasmussen <madsr@hey.com>
2024-02-06 13:19:30 +01:00
8c6e03d346 V14: Invalidate user tokens (#15651)
* Adding revoke user auth token handler and registering it

* Maintain method clarity by grouping new calls into its own method

* Rename functions to what they do

* Suggested linq function of tripple nesting

* Reduce nesting by early loop continuation

* Fix PR suggestion async typo

* Review suggestions

* Log msg alignment between members and users

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
2024-02-06 13:02:35 +01:00
71b3076de9 Members and member types in the Management API (#15662)
* Members and member types in the Management API

* Add validation endpoints for members

* Include validation result in service response + add unit tests

* Regenerate OpenApi.json

* Regenerate OpenApi.json after merge

* Don't throw an exception when trying to set valid variation levels for member types

* Added missing ProducesResponseType

* Remove TODO, as that works

* Allow creation of member with explicit key

* Do not feature "parent" for member creation + add missing response type

* Do not feature a "Folder" in create member type (folders are not supported)

* Added missing build methods

* Fixed issue with mapping

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2024-02-05 06:42:07 +01:00
Andreas ZerbstandGitHub dde2ccfd41 V14 QA fix failing acceptance tests on pipeline (#15652)
* Fixes, not done

* Fixed failing tests

* Fixes

* Updated tests

* Bumped version

* Did small adjustments

* Split tests out

* Skips failing package test

* Added missing semicolon

* Updated variables

* Added afterEach to ensureNameNotExists
2024-02-05 09:54:29 +07:00
Jacob Overgaard 52a9939480 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	.artifactignore
#	build/azure-pipelines.yml
#	tests/Umbraco.Tests.AcceptanceTest/misc/umbraco-linux.docker
2024-02-02 13:48:28 +01:00
2193ded62d V14 Added acceptance tests for Relation Types (#15653)
* Fixed failing tests

* Updated tests to use the updated helpers

* Clean up tests

* Enabled our pipeline for E2E testing

* Updated the CMS URl for our E2E tests

* Bumped version of our testHelpers

* Did some fixing, still a bit more to do

* Updated auth tests to use LoginUiHelper

* Updated Telemetry tests to use TelemetryUiHelper

* Updated LogViewer tests to use LogViewerUiHelper

* Updated api tests to apply AAA pattern and fix failed tests

* Removed unused import

* Added api tests for RelationType

* Added ui tests for Relation Type

* Bumped test helper version

* Added api tests for Relation Types

* Updated ui tests for Relation types

* Updated method due to the test helper changes

* Bumped version

* Fixed merged

* Update tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Relation Types/RelationTypes.spec.ts

Added ;

Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>

* Update tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Relation Types/RelationTypes.spec.ts

Updated name of method

Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>

* Update tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Relation Types/RelationTypes.spec.ts

Updated name of method

Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>

---------

Co-authored-by: Andreas Zerbst <andr317c@live.dk>
Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>
2024-02-01 19:46:49 +01:00
Jacob Overgaard 2f702b28ff update backoffice submodule 2024-02-01 16:13:42 +01:00
Jacob Overgaard 1f636583c3 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2024-02-01 15:58:33 +01:00
Jacob OvergaardandGitHub 0a6dd9538a add retry count for flaky test (#15632)
* add retry count for flaky test

* add retry to try and have test pass
2024-02-01 14:28:47 +01:00
Bjarke Berg 3a71eab1ce Merge remote-tracking branch 'origin/v14/dev' into v14/dev 2024-02-01 12:17:50 +01:00
d29e05efb7 Move document related operations to DocumentControllerBase (#15661)
* Clean up ContentControllerBase and move document related operations to DocumentControllerBase

* Rename content to document

---------

Co-authored-by: Elitsa <elm@umbraco.dk>
2024-02-01 11:29:52 +01:00
Bjarke Berg 9eb36c0234 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	Directory.Packages.props
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_10_0_0/AddMemberPropertiesAsColumns.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_10_2_0/AddHasAccessToAllLanguagesColumn.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_10_2_0/AddUserGroup2LanguageTable.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_10_3_0/AddBlockGridPartialViews.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_10_4_0/AddBlockGridPartialViews.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_10_5_0/AddPrimaryKeyConstrainToContentVersionCleanupDtos.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_10_7_0/MigrateTagsFromNVarcharToNText.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_11_3_0/AddDomainSortOrder.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_11_4_0/AlterKeyValueDataType.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_12_0_0/ResetCache.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_12_0_0/UseNvarcharInsteadOfNText.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_12_1_0/AddOpenIddict.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_12_1_0/TablesIndexesImprovement.cs
#	src/Umbraco.Web.UI.Docs/README.md
#	src/Umbraco.Web.UI.Docs/gulpfile.js
2024-02-01 11:24:43 +01:00
Kenn JacobsenandGitHub 296b7e061a Align presentation model factory naming (#15663) 2024-02-01 11:22:16 +01:00
Elitsa MarinovskaandGitHub a562198520 Rename items to item to be consistent (#15660) 2024-02-01 09:23:10 +01:00
74db02c444 V14: Don't add published culture infos if not published (#15370)
* Don't add published infos if not published

* Unpublish all cultures as a whole

* Added tests

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2024-02-01 08:33:14 +01:00
Kenn JacobsenandGitHub d631ef1802 Move the ContentControllerBase to the correct location (#15656) 2024-01-31 16:22:15 +01:00
0dd2beb484 V14: Update DataTypeControllerBase to use GetAllAsync() (#15641)
* Update to use GetAllAsync()

* Obsolete GetAll

---------

Co-authored-by: Elitsa <elm@umbraco.dk>
2024-01-31 15:00:47 +01:00
MoleandGitHub 008083f096 V14: Migration Cleanup (#15629)
* Remove obsoleted migrations

* Re-add default log queries

* Remove unused PreValueMigratorCollectionBuilder from DI

* Remove unused unit test

* Obsolete unused migrations

* Remove migrations prior to v13 from UmbracoPlan

* Fix whitespace

* Use array instead of IEnumerable

* Remove unused migrations
2024-01-31 12:45:56 +01:00
Kenn JacobsenandGitHub aaf7075313 Property level validation for Management API (#15644)
* Property level validation for content - initial implementation

* Always succeed create/update regardless of property level validation errors

* Move old complex editor validation classes to Web.BackOffice so they will be deleted

* Include operation status and property validation errors in ProblemDetails

* Refactor property validation to its own service(s)

* Make the problem details builder a little more generic towards extensions

* Validation for item and branch publish

* Moved malplaced test

* Get rid of a TODO

* Integration tests for content validation service

* Simplify validation service

* Add missing response types to create and update for document and media

* Remove test that no longer applies

* Use "errors" for model validation errors (property validation errors)

* Split create/update and validation into their own endpoints

* Fix forward merge

* Correct wrong assumption for missing properties

* Remove localization from validation error messages - decreases dependencies, adds a lot of obsolete constructors

* Reuse existing validation service + support custom error messages

* Fix merge errors

* Review comments
2024-01-31 10:40:58 +01:00
Jacob Overgaard e0e6dee896 update lockfile 2024-01-31 10:06:35 +01:00
8c8405bbbf V14: Fix up install controller (#15646)
* Rename InstallVResponseModel to InstallRequestModel

* Align SettingsInstallController

* Rename split DatabaseInstallResponseModel in two

* Change UserInstallResponseModel to UserInstallViewModel

* Use PresentationModel instead of ViewModel

* Use operation status pattern when validating database

* Prepare for install to return a message

* Begin updating steps

* Make StepBase sharable between upgrade and install

* Update steps

* Use error message from install steps in install controller

* Use error message from upgrade steps in upgrade controller

* Use 500 for install/upgrade failed

It's entirely likely that it has nothing to do with the request

* Updated OpenApi.Json

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2024-01-30 13:12:08 +01:00
Kenn JacobsenandGitHub 9b454bec6b Model mapping PoC (#15546)
* First take at new models for improved mapping between client and server

* Add variants to Media

* Re-introduced lost names

* Start breaking apart "Id" reference properties in request models as well

* Refactor to fix OpenAPI spec

* Discard TODO (not relevant)

* Split recycle bin response models

* Delete unused marker interface

* Use reference properties for content and media type handling

* Rework document and media types to be explicit in relations (do not expose "content type", it is an implementation detail)

* Mapping for document and media type copy + move

* Ensure correct response model for Media

* Regenerate OpenAPI JSON after forward merge

* Fix forward merge issues

* Fix forward merge + regenerate OpenApi.json

* Added unit tests for content state helper

* Move "allowed document types" endpoint to document type silo, refactored services and added "allowed media types"

* Regenerate OpenApi.json after forward merge

* Do not include content state for media items

* Review fix
2024-01-30 12:19:05 +01:00
bb46d23730 V14 Bugfix, fixed some of the document controllers (#15449)
* Updated naming to route correctly

* Added a check for null

* Added another status code for the PublicAccess

* Added a check for null

* Updated naming to match route

* Added attempt pattern

* added a ProblemDetailsBuilder for the EntryNotFound

---------

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2024-01-29 12:58:03 +01:00
Jacob Overgaard aea9b79513 update backoffice submodule 2024-01-26 15:55:30 +01:00
Nikolaj GeisleandGitHub e7749ecb58 V14/feature/more configuration endpoints (#15603)
* Add template configuration endpoint

* Implement template endpoint

* rename template configuration response model

* Implement package configuration endpoint

* Add media configuration endpoint

* Implement document configuration endpoint

* Refactor enabled to disabled

* implement document type configuratio endpoint

* Add required to view model properties

* Update OpenApi.json
2024-01-26 11:03:22 +01:00
Jacob Overgaard 170d91c183 ignore wwwroot in new ui temp project 2024-01-25 14:22:47 +01:00
Jacob Overgaard 2c13ce8877 add wwwroot/media to .gitignore 2024-01-25 14:20:47 +01:00
Andreas ZerbstandGitHub a93980b64c V14 Acceptance Test for the Package Section (#15618)
* In progress tests

* Updated createdPackaged tests

* Added test for checking if we are able to see the marketplace

* Added tests for checking if the correct message is shown

* Made quite a lot of changes, used the locators in the testHelpers. Added additional tests

* Updated to match changes to the Ui TestHelpers

* Fixed test

* added package file

* Bumped versions

* Updated naming

* Fixed Acceptance Test to match patterns

* Updated locator in test.

* Added Act comment

* Followed comments from PR
2024-01-25 16:56:25 +07:00
Bjarke Berg d8eef9eca5 Fix build 2024-01-24 11:24:40 +01:00
Bjarke Berg 91119308a2 Merge remote-tracking branch 'origin/v14/dev' into v14/dev 2024-01-24 11:12:45 +01:00
MoleandGitHub 76181a8af4 V14: Migrate JsonConfigManipulator to System.Text.Json (#15609)
* Minor cleanup

* Remove old obsoleted property

* Reimplement save connection string

* Remove old method using newtonsoft

* Implement RemoveConnectionStringAsync

* Implement SaveConfigValue

* Implement SaveDisableRedirectUrlTracking

* Cleanup

* Implement SetGlobalIdAsync

* Fix recursive default implementation

* Split manipulating dom and saving json

Otherwise SaveConnectionStringAsync would write twice.

* Add some documentation strings

* Reduce indentation

* Obsolete non-async methods

* Move JsonConfigManipulator to correct namespace and make it internal
2024-01-24 11:07:18 +01:00
Bjarke Berg 7a6b316f4b Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Infrastructure/PropertyEditors/BlockEditorPropertyValueEditor.cs
#	src/Umbraco.Infrastructure/PropertyEditors/NestedContentPropertyEditor.cs
#	src/Umbraco.Web.BackOffice/Security/BackOfficeSignInManager.cs
#	tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueEditorReuseTests.cs
#	version.json
2024-01-24 08:36:55 +01:00
Jacob Overgaard 80df1d17db Merge branch 'release/14.0' into v14/dev 2024-01-23 18:59:45 +01:00
aaca7a5ff4 2FA for users in management API (#15607)
* Added 2FA management endpoints

* Ensure not found do not lead to forbidden results

* Do not inherit the requirement to have access to users, from the current user base class

* Updated OpenApi.json

* Handle 2FA in login scenario (only backend)

* Added the endpoint to use for client to post 2FA code

* Fixed tests and allow injecting the authentication type settings

* fix test build

* Fallback to use Constants.Security.BackOfficeAuthenticationType

* remove unused variable

* Review fixes

* Build fix

* Update src/Umbraco.Cms.Api.Management/Controllers/User/Current/DisableTwoFactorProviderCurrentUserController.cs

Co-authored-by: Sven Geusens <geusens@gmail.com>

* Handle case where 2fa provider is already setup

---------

Co-authored-by: Sven Geusens <geusens@gmail.com>
2024-01-23 18:07:21 +01:00
Jacob Overgaard e9082dafa6 clean apidocs before upload 2024-01-23 16:43:27 +01:00
Jacob Overgaard 71651decbc variables probably do not work without a real stage dependency 2024-01-23 16:38:16 +01:00
Jacob Overgaard bfb500612a bump version to 14.0.0--preview005 2024-01-23 15:34:28 +01:00
Jacob Overgaard 7b99bdea9d remove unused parameter 2024-01-23 13:48:03 +01:00
Jacob Overgaard 789c47eb98 update backoffice submodule (signout) 2024-01-23 09:54:52 +01:00
8bf8483dcb V14 QA Added acceptance tests for Dictionary (#15479)
* Bumped version of TestHelper

* Added .udt test files

* Updated api tests for Dictionary

* Added ui tests for Dictionary

* Updated ui tets for Dictionary as TestHelper is changed

* Updated ui tests of Dictionary

* Updated verify step

* Fixed comments

* Imported crypto into Dictionary.spec.ts

Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>

* Fixed format

---------

Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>
2024-01-23 09:47:23 +01:00
Jacob Overgaard e21932283c update backoffice submodule 2024-01-23 09:07:48 +01:00
Bjarke Berg 0760fbd702 Increase timeout so we can figure out which tests are slow 2024-01-23 08:49:25 +01:00
26761cc04a Implemented culture based authorization for content (#15580)
* Implemented culture based authorization for content

* Implemented culture auth for create/update of documents

* Applied culture authorization to dictionary create/update

* Added an integration test to test an assumption about the ContentTypeEditingService.CreateAsync method

* Fix processing when result is already false;

* Apply suggestions from code review

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* Refactor method to async + clarify and consilidate comments regarding dictionary locks

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2024-01-22 21:08:20 +01:00
acc71b6d45 Add management api delete document endpoints (#15600)
* Added Delete document endpoint

* Added delete from recylebin endpoint

Added/restructured unittests

* Clarifications

* Moved document specific mapping from base recyclebin to document recyclebin

* Refactor OperationStatusResult mapping trough inheritance

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
2024-01-22 15:58:18 +01:00
Elitsa MarinovskaandGitHub bb0395349f V14: Fix composition endpoints namespaces (#15620)
* Fix namespace in media type related classes

* Fix namespace in document type composition related classes
2024-01-22 14:11:11 +01:00
e4f9f98f2d File system endpoints redo (#15521)
* First stab at a massive remake of file system based endpoints

* Do not prefix system paths with directory separator char

* Ensure correct and consistent response types

* Fix partial view snippets endpoints

* Clean up IO (path) operations

* Update OpenAPI JSON to match new endpoints

* Return 201 when renaming file system resources

* Add "IsFolder" to file system item endpoints

* Replace "parentPath" with a "parent" object for file system creation endpoints

* Update OpenAPI JSON

* Rewrite snippets

* Regenerate OpenAPI JSON after forward merge

* Remove stylesheet overview endpoint

* Regenerate OpenAPI JSON after forward merge

* add server-file-system module to importmap

* Expose generated resource identifier in 201 responses

---------

Co-authored-by: Mads Rasmussen <madsr@hey.com>
2024-01-22 08:20:45 +01:00
Jacob Overgaard 681903a1a7 update backoffice submodule 2024-01-19 13:32:33 +01:00
1fe39de589 Add missing empty recycle bin endpoints (#15602)
* Added empty document recyble bin

* Made EmptyDocumentRecycleBinController leaner

Cleaned up obsolete constructor

* Added empty media recycle bin endpoint

* Cleanup

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: Elitsa <elm@umbraco.dk>
2024-01-19 10:58:33 +01:00
Kenn JacobsenandGitHub 5429aa78a5 "Created at" responses should not have a response body (#15590) 2024-01-17 13:37:24 +01:00
43791c2b33 v14: Merge NewBackOfficeSettings into SecuritySettings. (#15586)
* Merge NewBackOfficeSettings into SecuritySettings.

* Apply suggestions from code review

Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>

* Remove hardcoded callback path

---------

Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
2024-01-17 13:26:09 +01:00
547da0b191 V14: Composition endpoints for Document and Media types (#15584)
* Adding response/request models

* Adding mapping

* Adding factory

* Adding controllers

* Moved to correct (generic domain) namespace

* Renamed to reflect the correct domain + renamed IsAllowed to IsCompatible

* Renaming + TODO

* Removed presentation logic + TODO

* Fixed controller

* Attempt for generic implementation

* Enable composition of media types + refactor content/media type editing tests to prove it (and a little renaming of a mis-named property)

* Remove unused classes

* Introducing GetAvailableCompositionsAsync to EditingServices

* Implement GetAvailableCompositionsAsync

* Base share implementation

* Tests

* Tests

* Renaming

* Clean up controller

* Clean up test

* Remove redundant check

* Create and use generic models

* Add shared implementation

* Fix and rename doc type mapper

* Fix document Type factory

* Add missing response type

* Create a base request model

* Make key nullable when new item

* Media type response models

* Default isElement to false and remove isElement param from media type related things

* Create mappings for media type compositions

* Inject generic base service to reuse implementation amongst concrete services

* Add new composition endpoints for media type

* Use specific type

* Add a reference comment to other test suite

* Add more test cases

---------

Co-authored-by: kjac <kja@umbraco.dk>
2024-01-17 08:36:27 +01:00
40a28a938c Management API for dynamic root and query steps. (#15505)
* Added management API for dynamic root and query steps.

* Open API

* Split models, use required and rename a little

* Rename query steps

* Make request culture and segment optional

* Introduce explicit back-office variation context

* Simplify query endpoint path

* Correct field naming

* Updated OpenApi.json

---------

Co-authored-by: kjac <kja@umbraco.dk>
2024-01-16 07:47:43 +01:00
Jacob Overgaard 852f0fb4a6 update backoffice submodule 2024-01-15 14:26:41 +01:00
Jacob Overgaard 201433fb71 update backoffice submodule 2024-01-15 11:57:59 +01:00
Jacob Overgaard 3f65046a7d update backoffice submodule 2024-01-15 11:45:35 +01:00
Bjarke Berg ea9226f169 Fixed exception type 2024-01-13 22:24:44 +01:00
Bjarke Berg eb8a27016e Fix merge issue with an old package reference 2024-01-13 21:27:24 +01:00
Bjarke Berg 9811eaebeb Post merge fix 2024-01-13 20:47:16 +01:00
Bjarke Berg aa6f704353 Merge remote-tracking branch 'origin/v14/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Infrastructure/BackgroundJobs/Jobs/OpenIddictCleanupJob.cs
2024-01-12 13:34:30 +01:00
664da17c39 V14 QA Fixed the failed acceptance tests (#15527)
* Fixed failing tests

* Updated tests to use the updated helpers

* Clean up tests

* Enabled our pipeline for E2E testing

* Updated the CMS URl for our E2E tests

* Bumped version of our testHelpers

* Did some fixing, still a bit more to do

* Updated auth tests to use LoginUiHelper

* Updated Telemetry tests to use TelemetryUiHelper

* Updated LogViewer tests to use LogViewerUiHelper

* Updated api tests to apply AAA pattern and fix failed tests

* Removed unused import

* Fixed comments

* Bumped version of test helper

* Updated the version to 10 instead of 11

* Updated the package-lock.json file to contain the correct versions

* Added a waitForTimeout
The reason for this is that this test is failing on the pipeline

* Bumped version of testhelpers

* Removed TODO

* Updated EnsurePathExists so we create the stylesheet and scripts folder

* Added a waits for response, otherwise our test would be too fast

* Sometimes it reloads before the save is complete

* Added timeout for locator

* Removed duplicate

* Wait until save

* This was an actual bug, so we should not use a workaround, we should fix it

* Skips the tests for script.

* Bug was fixed, so this can be used again

---------

Co-authored-by: Andreas Zerbst <andr317c@live.dk>
2024-01-12 13:32:25 +01:00
MoleandGitHub a8fd00a3b4 Make an exception for root path (#15570) 2024-01-12 12:29:23 +01:00
c5c24d36d9 V14: Copy and move endpoints for content and media types (#15553)
* Create new request models

* Create new structural operation status

* Handling of new structural operation status

* New CopyAsync and MoveAsync

* New endpoints

* Update schema

* Adding NotFound status

* Adding BadRequest response type

* Moving getbyid check to service

* Fix signature and implement get by id check in service

* Update OpenApi schema

* Use PUT instead of POST in "move" controllers

* Use PUT instead of POST in some more "move" controllers

---------

Co-authored-by: kjac <kja@umbraco.dk>
2024-01-12 08:59:21 +01:00
Ronald BarendseandBjarke Berg 05921ee6cc Refactor System.Runtime.Caching to Microsoft.Extensions.Caching.Memory 2024-01-11 14:26:19 +01:00
Ronald BarendseandBjarke Berg ace5c54da2 Remove unused/untested dependent files support from IAppPolicyCache 2024-01-11 14:25:54 +01:00
Bjarke BergandGitHub e291fae01e Migrated ReportSite, OpenIddictCleanup and TemporaryFileCleanup to background jobs (#15555)
* Migrated ReportSite, OpenIddictCleanup and TemporaryFileCleanup to the new background jobs introduced in v13.

* Fixed delay and period
2024-01-11 13:18:10 +01:00
MoleandGitHub 416c19854d V14: Migrate examine integration tests to V14 (#15536)
* Begin migrating test to use new service calls

* Fix formatting

* Add todo to add timeout so our tests dont stall entirely

* Add timeout so tests can run

Still need to figure out why the index only seems to update sometimes

* Migrate BackOfficeExamineSearcherTests to use new service calls

* Remove unused imports

* Migrate to languageservice in external index searcher test

* Use seperate save and publish calls

* Use scopes in ExamineExternalIndexTests

* Use scopes in BackOfficeExamineSearcherTests
2024-01-11 11:12:47 +01:00
8516a7b2e5 V14: Add security related configurations (#15557)
* Implement user configuration endpoint

* Add password configuration factory

* refactor users to use new password configuration model

* Implement current user configuration endpoint

* Add auth policy

* Refacor current user to use PasswordConfigurationReponseModel

* Implement configuration security controller

* Rename property to less confusing name

* Add version to ConfigurationSecurityController.cs

* Review changes

---------

Co-authored-by: kjac <kja@umbraco.dk>
2024-01-11 10:30:22 +01:00
33f2b26bf6 [v14] Absolute media urls (#15503)
* Made a replaceble solution to support absolute urls for media/user avatars in the management API

* PR suggestion

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* PR suggestion

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* PR suggestion/fix and added missing switch case

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2024-01-10 10:01:06 +01:00
a6ccd5a7a9 Implement temporary file configuration endpoint (#15518)
* Implement temporary file configuration endpoint

* Update MaxfileSize to be a string.

* Make max file size a nullable integer

---------

Co-authored-by: Elitsa <elm@umbraco.dk>
2024-01-10 09:20:29 +01:00
Bjarke Berg 5f4c8ea0bf Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Cms.StaticAssets/umbraco/UmbracoBackOffice/Default.cshtml
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Login/login.spec.ts
2024-01-10 08:36:50 +01:00
3acda751b9 v14: Add Preview controller (#15481)
* Add Preview controller

* Implement PreviewService

* Add tests for endpoints.

* Add Authorization to previews

* Apply suggestions from code review

Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com>

---------

Co-authored-by: Elitsa <elm@umbraco.dk>
Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com>
2024-01-09 15:51:59 +01:00
c937d0f2ed V14/feature/management tree count by take zero (#15308)
* Allow Tree endpoints that query entities to return count without entity data

* Apply count by take 0 in FileSystem Endpoints

* Apply count by take 0 in Dictionary Endpoints

* Apply count by take 0 in RootRelationType Endpoints

* Revert PaginationService takeZero flag as it only guards against things that already blow up

* Mark PagedResult as Obsolete as we want to step away from classic pagination system to skip/take

* Pushed management api RelationType pagination and async preperation down to the service layer

* Scope fix and allocation optimizations

* Pushed management api dictionary pagination and down to the service layer

Also did some nice allocation optimizations

* PR feedback + related strange count behaviour

* Moved count by pagesize logic from EntryController to service

* A tiny bit of formatting and comments

* Fix bad count filter logic

* Added integration tests for creating datatypes in a folder

* Added tests for count testing on TreeControllers

- ChildrenDataType
- RootDataType
- ChildrenDictionary
- RootDictionary
- ChildrenDocument
- RootDocument
- RootBluePrint
- RootDocumentType
- ChildrenDocumentType

* Revert "Added tests for count testing on TreeControllers", should be on services

This reverts commit ee2501fe62.
This reverts commit 808d5b276f.

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: kjac <kja@umbraco.dk>
Co-authored-by: Andreas Zerbst <andr317c@live.dk>
2024-01-02 13:53:24 +01:00
Elitsa MarinovskaandGitHub f3cb8fe117 V14: User token revocation and session sign-out (#15511)
* Fix token revocation endpoints registration for .well-known

* Add logout and revocation endpoints to OpenIddict permissions

* Register urls for post_logout_redirect_uri

* Create /signout endpoint
2024-01-02 13:42:39 +01:00
674c48ab9a V14: Add optional key to template create model (#15471)
* Implement Id for request model

* Make key optional

* Add test for use case

---------

Co-authored-by: Elitsa <elm@umbraco.dk>
2024-01-02 08:57:07 +01:00
f026010102 Implement server configuration (#15507)
Co-authored-by: Elitsa <elm@umbraco.dk>
2023-12-29 13:47:44 +01:00
Bjarke Berg 1bf13b4ad4 Remove legacy file upload attribute usage 2023-12-22 15:49:33 +01:00
Bjarke Berg 6395feb3a3 Remove the DataTypeSplitDataCollector.cs 2023-12-22 15:48:53 +01:00
Bjarke Berg 1e849ad539 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	Directory.Build.props
#	src/Umbraco.Web.BackOffice/Controllers/ContentController.cs
2023-12-22 14:19:04 +01:00
fc71724386 V14: Server information (#15497)
* Rename information endpoint to troubleshooting

* Rename information endpoint to troubleshooting

* Add new information endpoint

* Fix bad merge

* Add InformationServerController.cs back

* Update serverTime offset to non hard-coded value.

* Add dictionary to swagger models

* Update OpenApi.json file

* Rename map definition

* Add ServerConfigurationBaseModel

* Implement ServerConfigurationBaseModel.cs

* Updated OpenApi

* Updated endpoint to return correct type in openapi

* Use explicit class for server information

* Remove version endpoint, as that is contained in server information.

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-12-22 10:21:11 +01:00
8acb5665e8 Add post and delete methods to user-group/id/users to add/remove user… (#15490)
* Add post and delete methods to user-group/id/users to add/remove users from group

* Update OpenApi contract

* PR feedbac

Moved fetch usergroup logic into service layer
Renamed methods to async

* Naming

* Introduced user not found on UserGroupOperationStatus, as otherwise the return message is wrong

* Added authentication

* Removed authorization from the service layer as its determined that that responsibiliity does not belong there.

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-12-22 08:05:45 +01:00
Bjarke Berg 4b3131fda4 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-12-20 15:17:37 +01:00
Jacob Overgaard 7694588c86 update backoffice submodule 2023-12-18 14:32:32 +01:00
Jacob OvergaardandGitHub 650a9dad3b add the cors policy as first item on the pipeline filter (#15472)
this ensures that any assets loaded as "modules" also get the right Access-Control-Allow-* headers
2023-12-18 14:19:53 +01:00
Kenn JacobsenandGitHub c2b970d0de Make "create folder" return HTTP 201 Created for file system folders (#15459)
* Make "create folder" return 201 and add expected return types to "create" and "delete" for all file system folder endpoints

* Update OpenApi.json
2023-12-18 11:01:53 +01:00
Jacob Overgaard 32cecbe14f update backoffice submodule 2023-12-16 11:01:01 +01:00
Jacob Overgaard 6df3b5bd66 update backoffice submodule 2023-12-16 09:47:06 +01:00
Jacob Overgaard bb43db2601 update backoffice submodule 2023-12-16 09:14:56 +01:00
Jacob Overgaard 786f584de9 update backoffice submodule 2023-12-15 10:29:49 +01:00
Jacob Overgaard 38b4e44479 update backoffice submodule 2023-12-15 09:48:32 +01:00
Elitsa MarinovskaandGitHub dbdf3cf03d V14: Tighten permissions for folder controllers (#15457)
* Fixing folder controller policies

* Remove unused policy
2023-12-14 15:03:35 +01:00
b4ca478f2c Required on view models (#15356)
* Added required on view models

* Updated OpenApi.json

* mark all fields required

* Force non-nullable as required.

* Missing import

* Update OpenApi.json

---------

Co-authored-by: Mads Rasmussen <madsr@hey.com>
2023-12-14 11:46:02 +01:00
Niels LyngsøandGitHub d368bd3ebf Update import maps (#15446)
* append 'property' and 'static-file'

* latest front-end commit
2023-12-14 11:45:44 +01:00
MoleandGitHub db9dc4a20d Rename user controller files to match class names (#15442) 2023-12-14 10:36:43 +01:00
Bjarke Berg 93fe9f3dea build 2023-12-14 09:04:23 +01:00
Bjarke Berg baf29649c9 Move package to central 2023-12-14 08:42:20 +01:00
Bjarke Berg d1b53c0ec9 Added ignore on new tests (Temporarily) 2023-12-13 16:34:17 +01:00
Bjarke Berg f8dda5a7b5 Post merge fixes 2023-12-13 16:25:28 +01:00
Bjarke Berg 95094361cc Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	Directory.Packages.props
#	build/azure-pipelines.yml
#	src/Umbraco.Cms.Api.Delivery/Handlers/InitializeMemberApplicationNotificationHandler.cs
#	src/Umbraco.Cms.StaticAssets/umbraco/UmbracoBackOffice/Default.cshtml
#	src/Umbraco.Cms.StaticAssets/umbraco/UmbracoLogin/Index.cshtml
#	src/Umbraco.Core/DependencyInjection/UmbracoBuilder.CollectionBuilders.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
#	src/Umbraco.Infrastructure/Models/Blocks/BlockListEditorDataConverter.cs
#	src/Umbraco.Infrastructure/PropertyEditors/BlockListPropertyEditorBase.cs
#	src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs
#	src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockListPropertyValueCreator.cs
#	tests/Directory.Packages.props
#	tests/Umbraco.Tests.AcceptanceTest/package.json
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockListEditor/blockListEditorDataType.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/HelpPanel/helpLinks.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Login/login.spec.ts
#	tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/BlockListPropertyValueConverterTests.cs
#	version.json
2023-12-13 15:34:22 +01:00
Nhu DinhandGitHub ced1a82c4e Renamed GetRichTextRulesByPath controller (#15443) 2023-12-13 10:58:56 +01:00
7fdd342643 PropertyEditor(UI)Alias name refactor (#15408)
* PropertyEditor(UI)Alias name refactor

* Updated OpenApi.json

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-12-13 09:50:52 +01:00
Jacob Overgaard 81b23a60a4 update backoffice submodule 2023-12-11 16:05:26 +01:00
fda866fc9e V14: Add authorization policies to Management API controllers - p2 (#15211)
* Making ProblemDetails details more generic

* Adding authorizer that can be replaces for external authz in handlers. Adding handler and requirement for UserBelongsToUserGroupInRequest policy

* Adding method to get the GUID from claims

* Adding service methods to check user group authz

* Porting MustSatisfyRequirementAuthorizationHandler

* Adding controllers authz

* Fix return status code + produced response type

* Moving to folder

* Adding DenyLocalLogin policy scaffold

* Implement a temp DenyLocalLoginHandler

* Introducing a new Fobidden result

* Fix comment

* Introducing a helper class for authorizers

* Changed nullability for GetCurrentUser

* Changes from Attempt to Status + FIXME comments

* Create a UserGroupAuthorizationStatus to be used in the future

* Introduces a new authz status for checking media acess

* Introducing a new permission service for media

* Adding fixme

* Adding more policy configurations

* Adding Media policy requirement and handler

* Adding media authorizer

* Fix order of params

* Adding duplicate code comment

* Adding authz to media controllers

* Migrating more logic from MediaPermissions.cs

* Adding more MediaAuthorizationStatus-es

* Handling of new authorization status

* Fix comment

* Adding NotFound case

* Adding NewDenyLocalLoginIfConfigured policy && commenting [AllowAnonymous] where the policy is applied since it is already handled

* Changed Forbid() to Forbidden() to get the correct status code

* Remove policy that is applied on the base controller already

* Implement and apply NewUmbracoFeatureEnabled policy

* Renaming classes to add Permission in the name

* Register permission services

* Add FIXME

* Introduce new IUserGroupPermissionService and refactor accordingly

* Add single overload with default implementation

* Adding user permission policy and related

* Applying admin policy

* Register all new policies

* Better wording

* Add default implementation for a single overload

* Adding remarks to IContentPermissionService.cs

* Supporting null as key in ContentPermissionService

* Fix namespace

* Reverting back to not supporting null as content key, but having dedicated implementation

* Adding content authorizer with null values to represent root item

* Removing null key support and adding dedicated implementation

* Removing remarks

* Adding content resource with null support

* Removing null support

* Adding requirement and status

* Adding content authorizer + handlers

* Applying policies to content controllers

* Update comment

* Handling of Authorization Statuses

* More authz in controllers

* Fix comments

* New branch handler

* Obsolete old implementation

* Adding dedicated policies to root and bin

* Adding a branch specific namespace

* Bin specific requirement and namespace

* Root specific requirement and namespace

* Changing to new root policy

* Refactoring

* Save policies

* Fix null check/reference

* Add TODO comment

* Create media root- and bin-specific policies, handlers, etc.

* Apply correct policy in create and update media controllers

* Apply root policy to move and sort controllers

* Fix wording

* Adding UserGroupAuthorizationStatusResult

* Remove all AuthorizationStatusResult as we cannot get the specific AuthorizationStatus

* Fixing Umbraco feature policy

* Fix allow anonymous endpoints - the value returned from DenyLocalLoginHandler wasn't enough, we need to succeed DenyAnonymousAuthorizationRequirement as it is required for some of the endpoints that had the attribute

* Apply DenyLocalLoginIfConfigured policy to corresponding re-implementation of PostSetInvitedUserPassword

* Fix comment

* Renaming performingUser to user and fixing comments

* Rename helper method

* Fix references

* Re-add merge conflict deletion

* Adding Backoffice requirement and relevant

* Registering

* Added a simple policy test

* Fixed small test things and clean up

* Temp solution

* Added one more test and fix another static issue

* Fix another merge conflict

* Remove BackOfficePermissionRequirement and handler as they might not be necessary

* Comment out again [AllowAnonymous]

* Remove AuthorizationPolicies.BackOfficeAccessWithoutApproval policy as it might not be necessary

* Fix temp implementation

* Fix reference to correct handler

* Apply authz policy to new publish/unpublish controllers

* Fix comments

* Removing duplicate ProducesResponseTypes

* Added swagger documentation about the 401 and 403

* Added Resources to Media, User and UserGroup

* Handle root, recycle bin and branch in the same handler

* Handle both parent and target when moving

* Check Ids for all sort requests

* Xml docs

* Clean up

* Clean up

* Fix build

* Cleanup

* Remove TODO

* Added missing overload

* Use yield

* Adding some keys to check

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
Co-authored-by: Andreas Zerbst <andr317c@live.dk>
2023-12-11 08:25:29 +01:00
Jacob Overgaard f8b95e5c69 update backoffice submodule 2023-12-07 10:06:46 +01:00
Jacob Overgaard f5a49d87c3 update backoffice submodule 2023-12-06 15:32:47 +01:00
Kenn JacobsenandGitHub 4e6b9af959 Allow specifying root access for user groups (#15364) 2023-12-06 10:18:32 +01:00
Jacob Overgaard 1be548b680 Update nightly build (#15359)
* cherry-pick templateParameters from v14/dev

* add isNightly parameter

* remove v9

* add parameter check for myget isNightly
2023-12-05 13:11:15 +01:00
Jacob OvergaardandGitHub cd10d5840d V14: Publish Bellissima package to npm via Pipelines (#14926)
* ignore node_modules specifically to limit size of build_output

* build and publish backoffice artifacts

* instruct GitVersioning to output all variables such as npm to use in Pipelines

* use NBGV variables

* prepare npm package for nightlies

* instruct to deploy to MyGet for nightlies

* Deploy to npm only after Myget

* add public access to publish

* write scopes to .npmrc file

* add scope to registry.npmjs.org

* nightly param
2023-12-05 10:54:23 +01:00
48befe730b V14 QA Refactor code of Partial View acceptance tests (#15325)
* Refactor acceptance tests for Partial View

* Refactor api tests for Partial View

* Bumped version of Test Helper

* Added suggestion from review

* Bumped version to testhelpers 2.0.8

---------

Co-authored-by: Andreas Zerbst <andr317c@live.dk>
2023-12-01 11:20:57 +01:00
Kenn JacobsenandGitHub f9ecd9514e Management API should expose if a user group is a system group (#15333) 2023-12-01 09:39:27 +01:00
Kenn JacobsenandGitHub 42234cdd40 Move system information away from the User API (#15316)
* Move system information away from the User API

* Review comments
2023-11-30 14:29:16 +01:00
Bjarke Berg 53d0057ac6 Update test dependencies 2023-11-29 12:46:28 +01:00
Kenn JacobsenandGitHub c9c234492b Add missing API version attributes to management API controllers (#15310) 2023-11-29 09:23:23 +01:00
Bjarke Berg ddf9f05a8f Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
#	tests/Umbraco.Tests.AcceptanceTest/package-lock.json
#	version.json
2023-11-28 15:18:24 +01:00
Bjarke Berg 17ea20ee3d Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Cms.StaticAssets/umbraco/UmbracoBackOffice/Default.cshtml
#	src/Umbraco.Cms.StaticAssets/umbraco/UmbracoInstall/Index.cshtml
#	src/Umbraco.Cms.StaticAssets/umbraco/UmbracoLogin/Index.cshtml
2023-11-28 15:09:48 +01:00
Jacob Overgaard 98e2a1b897 update backoffice submodule 2023-11-28 13:54:03 +01:00
d6f0c33d83 V14 added acceptance tests for the Stylesheets (#15265)
* Added acceptance test for Stylesheets

* Updated api test for stylesheet using new helpers and apply AAA pattern

* Bumped version of Test Helpers

* Updated api and ui tests of Stylesheet after modifying TestHelper

* Updated stylesheets ui tests using openActionMenuAtRoot()

* Added suggestions from review

* Added wait for the flaky tests

* Fixed package-lock.json

---------

Co-authored-by: Andreas Zerbst <andr317c@live.dk>
2023-11-23 09:33:51 +01:00
Jacob Overgaard e04b015026 update backoffice submodule 2023-11-22 16:19:55 +01:00
012b43a1c2 Publishing in the Management API (#14774)
* make CoreScopeProvider available for derived classes

* Create publish controller

* Add publish functionality

* Remove unneeded using

* Implement publish for multiple cultures

* support multiple cultures in controler

* Dont validate properties

* Refactor to use PublishingOperationStatus

* refactor to use proper publish async methods

* Refactor publish logic into own service

* Commit some demo code

* Add notes about what errors can happen when publishing

* Rework ContentPublishingService and introduce explicit Publish and PublishBranch methods in ContentService

* Fix merge

* Allow the publishing strategy to do its job

* Improved check for unsaved changes

* Make the old content controller work (as best possible)

* Remove SaveAndPublish (SaveAndPublishBranch) from all tests

* Proper guards for invalid cultures when publishing

* Fix edge cases for property validation and content unpublishing + add unpublishing to ContentPublishingService

* Clear out a few TODOs - we'll accept the behavior for now

* Unpublish controller

* Fix merge

* Fix branch publish notifications

* Added extra test for publishing unpublished cultures and added FIXME comments for when we fix the state of published cultures in content

---------

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
Co-authored-by: Zeegaan <nge@umbraco.dk>
2023-11-22 12:52:08 +01:00
Elitsa MarinovskaandGitHub 42dd2da579 V14: Allowing custom backoffice host with CORS policy (#15269)
* Allowing custom backoffice host with CORS policy

* Adding missing allow
2023-11-21 15:49:29 +01:00
Elitsa MarinovskaandGitHub 8274822577 V14: Start using user group permission service (#15200)
* Adding a replacement to IUserGroupAuthorizationService

* Replacement for the implementation as well

* Adding AuthorizationStatus & mapping it to the corresponding OperationStatus

* Fix references

* Fix another reference

* Fix statuses

* Fix status result messages

* Fix wording

* Moving check for user part of user group earlier

* Review suggestion

* Fix section name
2023-11-17 11:52:29 +01:00
Nhu DinhandGitHub dc79b84700 V14 added acceptance tests for the Partial Views (#15210)
* add UI acceptance tests for Partial Views

* Added additional timeout

* fixed comments

* Fixed suggestions from review
2023-11-17 08:24:31 +01:00
Andreas ZerbstandGitHub 8b5717500d V14 QA added Scripts acceptance tests (#15212)
* Updated api script tests for using new helpers and the AAA pattern

* Added acceptance tests for the scripts

* updated naming

* Bumped version of testHelpers

* Added suggestions from review
2023-11-17 10:11:43 +07:00
Jacob Overgaard 549b219a8b update backoffice submodule 2023-11-16 15:24:32 +01:00
Jacob Overgaard 30ee7ae045 update backoffice submodule 2023-11-16 15:23:41 +01:00
Bjarke Berg 5b3e9c580a Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	version.json
2023-11-16 09:12:01 +01:00
Bjarke Berg 696867b305 Merge remote-tracking branch 'origin/v14/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
2023-11-16 09:08:30 +01:00
Bjarke Berg fb55e1b244 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs
#	src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Repositories.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
#	src/Umbraco.Infrastructure/PropertyEditors/MultiUrlPickerValueEditor.cs
2023-11-14 13:22:10 +01:00
c5c8a59736 Allow ID for a new dictionary-item to be specified (#15187)
* Allow ID for a new dictionary-item to be specified

* PR: Pattern matching hotness

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2023-11-14 13:01:59 +01:00
Mads RasmussenandGitHub 7d9db0ab30 update import map for data type (#15199) 2023-11-14 12:27:35 +01:00
Andreas ZerbstandGitHub 3d6c5850dc V14 added test for the Templates (#15179)
* Updated existing locator as it was prone to failing

* Removed old tests from earlier versions

* Added a timeout and an await. This was because the locator sometimes failed

* Added missing import for crypto

* Updated locator as it sometimes failed.

* Updated the README to include information for using the UI mode for playwright

* Bumped the timeout time for our tests

* We updated the naming for out methods in our testHelpers, so we need to update the usage as well

* Added additional timeout

* Updated the config so it is easier to understand what you need to input

* Added UI acceptance tests for templates

* Added types/node, allows us to use crypto. Updated the testhelpers to use the newest version.

* fixed error with testhelper dependency

* Bumped testhelper version

* Moved to settings instead of templating
2023-11-13 09:36:23 +01:00
Kenn JacobsenandGitHub 589c74e918 Data type icons should not be served from the Management API (#15155)
* Remove data type icons from management API output and add editor UI alias instead

* Update OpenApi.json
2023-11-10 14:17:50 +01:00
Jacob Overgaard a0ff997ab0 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-11-10 13:49:54 +01:00
Jacob OvergaardandGitHub c03df2b74e V14: make v13 login screen work initially with Management API (#15170)
* make the login check a bit more robust to be able to handle both old postlogin and new management api response types

* v14 only: update the login url to work with the management api (this will still work with the old backoffice to some extent)

* Revert "v14 only: update the login url to work with the management api (this will still work with the old backoffice to some extent)"

This reverts commit 0639ca80f0.

* V14 only: additionally authenticate with the Management API to set the right cookies
2023-11-10 13:38:08 +01:00
Bjarke Berg e13ab13183 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	Directory.Build.props
#	src/Umbraco.Core/CompatibilitySuppressions.xml
#	src/Umbraco.Infrastructure/CompatibilitySuppressions.xml
#	src/Umbraco.Web.BackOffice/CompatibilitySuppressions.xml
#	src/Umbraco.Web.Common/CompatibilitySuppressions.xml
#	tests/Umbraco.Tests.Common/CompatibilitySuppressions.xml
#	tests/Umbraco.Tests.Integration/CompatibilitySuppressions.xml
2023-11-09 09:41:39 +01:00
Bjarke Berg e9857c800a Merge remote-tracking branch 'origin/v14/dev' into v14/dev 2023-11-09 07:57:00 +01:00
Jacob Overgaard 1f4bbe2f06 update backoffice submodule 2023-11-08 14:39:46 +01:00
Bjarke Berg fd0c233362 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-11-08 05:53:03 +01:00
Bjarke Berg 5e37b997af Merge remote-tracking branch 'origin/v14/dev' into v14/dev 2023-11-08 05:52:35 +01:00
2f4f2ae384 V14/feature/custom generic swagger (#15025)
Co-authored-by: Sven Geusens <sge@umbraco.dk>
2023-11-07 16:15:56 +01:00
Andreas ZerbstandGitHub 66ea4fe29a V14 QA Added Log Viewer Tests (#15108)
* Added log viewer tests, not done yet

* Updated auth to work

* Updated the authentication test

* Cleaned up the Logviewer tests

* Removed old acceptance tests

* Fixed failing test

* Updated old tests and added additional log viewer tests

* Bumped version and deleted duplicate dependencies

* Fixed naming

* Added a TODO
2023-11-06 11:33:25 +01:00
Jacob Overgaard 3f4bb50a98 update backoffice submodule 2023-11-02 16:50:12 +01:00
Jacob Overgaard 2bbd5fa541 update backoffice submodule 2023-11-02 16:32:06 +01:00
Jacob Overgaard 0a65f0a576 lockfile 2023-11-02 14:06:21 +01:00
Bjarke Berg 83ed42998a Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-11-02 13:12:46 +01:00
Kenn JacobsenandGitHub 0f91ed895d Merge pull request #15100 from umbraco/v14/feature/merge-01-11-2023
V13 to V14 merge 01-11-2023
2023-11-02 12:38:26 +01:00
kjac e864f3eb05 Fix merge errors and port blocks in RTE implementation to V14 format (strongly typed, no magic JObjects) 2023-11-02 11:55:12 +01:00
Bjarke Berg ef80e25aa6 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	build/azure-pipelines.yml
#	src/Umbraco.Core/Constants-Configuration.cs
#	src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs
#	src/Umbraco.Core/Factories/IDatabaseSettingsFactory.cs
#	src/Umbraco.Core/Factories/IInstallSettingsFactory.cs
#	src/Umbraco.Core/Factories/IUpgradeSettingsFactory.cs
#	src/Umbraco.Core/Factories/InstallSettingsFactory.cs
#	src/Umbraco.Core/Factories/UpgradeSettingsFactory.cs
#	src/Umbraco.Core/Factories/UserSettingsFactory.cs
#	src/Umbraco.Core/Installer/IInstallStep.cs
#	src/Umbraco.Core/Installer/IUpgradeStep.cs
#	src/Umbraco.Core/Installer/NewInstallStepCollection.cs
#	src/Umbraco.Core/Installer/NewInstallStepCollectionBuilder.cs
#	src/Umbraco.Core/Installer/Steps/FilePermissionsStep.cs
#	src/Umbraco.Core/Installer/Steps/RestartRuntimeStep.cs
#	src/Umbraco.Core/Installer/Steps/TelemetryIdentifierStep.cs
#	src/Umbraco.Core/Installer/UpgradeStepCollection.cs
#	src/Umbraco.Core/Installer/UpgradeStepCollectionBuilder.cs
#	src/Umbraco.Core/Models/Blocks/RichTextBlockLayoutItem.cs
#	src/Umbraco.Core/Models/Blocks/RichTextEditorBlockDataConverter.cs
#	src/Umbraco.Core/Models/Configuration/NewBackOfficeSettings.cs
#	src/Umbraco.Core/Models/Configuration/NewBackOfficeSettingsValidator.cs
#	src/Umbraco.Core/Models/Installer/ConsentLevelModel.cs
#	src/Umbraco.Core/Models/Installer/DatabaseInstallData.cs
#	src/Umbraco.Core/Models/Installer/DatabaseSettingsModel.cs
#	src/Umbraco.Core/Models/Installer/InstallData.cs
#	src/Umbraco.Core/Models/Installer/InstallSettingsModel.cs
#	src/Umbraco.Core/Models/Installer/PasswordSettingsModel.cs
#	src/Umbraco.Core/Models/Installer/UpgradeSettingsModel.cs
#	src/Umbraco.Core/Models/Installer/UserInstallData.cs
#	src/Umbraco.Core/Models/Installer/UserSettingsModel.cs
#	src/Umbraco.Core/Models/OutOfDateType.cs
#	src/Umbraco.Core/PaginationHelper.cs
#	src/Umbraco.Core/Services/Installer/IInstallService.cs
#	src/Umbraco.Core/Services/Installer/IUpgradeService.cs
#	src/Umbraco.Core/Services/Installer/InstallService.cs
#	src/Umbraco.Core/Services/Installer/UpgradeService.cs
#	src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Repositories.cs
#	src/Umbraco.Infrastructure/Factories/Installer/DatabaseSettingsFactory.cs
#	src/Umbraco.Infrastructure/Installer/Steps/CreateUserStep.cs
#	src/Umbraco.Infrastructure/Installer/Steps/DatabaseConfigureStep.cs
#	src/Umbraco.Infrastructure/Installer/Steps/DatabaseInstallStep.cs
#	src/Umbraco.Infrastructure/Installer/Steps/DatabaseUpgradeStep.cs
#	src/Umbraco.Infrastructure/Installer/Steps/RegisterInstallCompleteStep.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
#	src/Umbraco.Infrastructure/Models/Blocks/BlockEditorDataConverter.cs
#	src/Umbraco.Infrastructure/PropertyEditors/BlockEditorPropertyValueEditor.cs
#	src/Umbraco.Infrastructure/PropertyEditors/BlockEditorValidator.cs
#	src/Umbraco.Infrastructure/PropertyEditors/BlockEditorValues.cs
#	src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs
#	src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockGridPropertyValueConverter.cs
#	src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs
#	src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockPropertyValueConverterBase.cs
#	src/Umbraco.Infrastructure/Security/IBackOfficeApplicationManager.cs
#	src/Umbraco.Infrastructure/Services/IIndexingRebuilderService.cs
#	src/Umbraco.Infrastructure/Services/IndexingRebuilderService.cs
#	src/Umbraco.New.Cms.Core/Umbraco.New.Cms.Core.csproj
#	src/Umbraco.New.Cms.Infrastructure/Umbraco.New.Cms.Infrastructure.csproj
#	src/Umbraco.New.Cms.Web.Common/Umbraco.New.Cms.Web.Common.csproj
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/content.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Login/login.spec.ts
#	tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/BlockListPropertyValueConverterTests.cs
#	version.json
2023-11-01 13:50:38 +01:00
Bjarke Berg e159124643 Merge branch 'v14/feature/merge-29-10-2023' into v14/dev 2023-11-01 12:41:12 +01:00
Bjarke Berg 2856dc19a4 revert wrong merge for installer 2023-11-01 12:22:52 +01:00
Jacob Overgaard 985799068b update backoffice submodule 2023-10-31 16:46:28 +01:00
Jacob Overgaard fe8fe821d4 update backoffice submodule 2023-10-31 15:14:18 +01:00
Jacob Overgaard 0281b71dc8 update importmap 2023-10-31 11:50:35 +01:00
6c5d38eb1a V14/feature/resend user invite endpoint (#14985)
* Added endpoint to resend invites for users.

* improve async return signatures + usings cleanup

* Improve/fix controller details

* Small improvements/clarifications

* Minor whitespace and naming fixes

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-10-31 10:07:30 +01:00
Jacob Overgaard bf6b2b1939 add new imports 2023-10-31 09:19:46 +01:00
Jacob Overgaard 7a750da8aa update build markers for StaticAssets to support Belle, Bellissima, Auth, and Login 2023-10-31 08:01:24 +01:00
Jacob Overgaard 8e925cb44c add condition to allow V13 and V14 login screens to work simultaneously 2023-10-30 15:58:29 +01:00
Jacob Overgaard 230164efd8 update backoffice submodule to ensure "auth app" is set to output its files properly 2023-10-30 15:45:38 +01:00
Jacob Overgaard 060ce40475 set new v14 "auth app" to output its files into a new "auth" folder to ensure it doesnt conflict with v13 login screen 2023-10-30 15:44:02 +01:00
Jacob Overgaard ca03034afb Add UmbracoLogin/Index.cshtml from V13 into the Umbraco.Web.UI executable to override the V14 login screen 2023-10-30 15:43:02 +01:00
Jacob Overgaard ebef3e2359 The default login view should be the v14 compliant login component until the v13 login screen is migrated properly 2023-10-30 15:42:31 +01:00
Bjarke Berg bd0a8bfdf7 post merge 2023-10-30 15:13:12 +01:00
Bjarke Berg dfe5dfa4c1 Merge remote-tracking branch 'origin/v14/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs
#	src/Umbraco.Core/DeliveryApi/IApiContentQueryProvider.cs
#	src/Umbraco.Core/DeliveryApi/IApiContentQueryService.cs
#	src/Umbraco.Core/Services/ITagService.cs
#	src/Umbraco.Core/Services/UserService.cs
#	src/Umbraco.Web.BackOffice/Controllers/MediaController.cs
2023-10-26 09:50:08 +02:00
Bjarke Berg e147c93cf9 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	Directory.Build.props
#	build/azure-pipelines.yml
#	src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs
#	src/Umbraco.Cms.Api.Common/OpenApi/SwaggerRouteTemplatePipelineFilter.cs
#	src/Umbraco.Cms.Api.Common/Security/Paths.cs
#	src/Umbraco.Cms.Api.Delivery/Controllers/Security/MemberController.cs
#	src/Umbraco.Cms.Api.Delivery/DependencyInjection/UmbracoBuilderExtensions.cs
#	src/Umbraco.Cms.Api.Delivery/Handlers/InitializeMemberApplicationNotificationHandler.cs
#	src/Umbraco.Cms.Api.Delivery/Handlers/RevokeMemberAuthenticationTokensNotificationHandler.cs
#	src/Umbraco.Cms.Api.Delivery/Security/MemberApplicationManager.cs
#	src/Umbraco.Cms.Api.Delivery/Services/RequestMemberAccessService.cs
#	src/Umbraco.Cms.StaticAssets/umbraco/UmbracoBackOffice/Default.cshtml
#	src/Umbraco.Cms.StaticAssets/umbraco/UmbracoLogin/Index.cshtml
#	src/Umbraco.Core/Constants-OAuthClaims.cs
#	src/Umbraco.Core/Constants-OAuthClientIds.cs
#	src/Umbraco.Core/DeliveryApi/IApiContentQueryProvider.cs
#	src/Umbraco.Core/DeliveryApi/IApiContentQueryService.cs
#	src/Umbraco.Core/DeliveryApi/IRequestMemberAccessService.cs
#	src/Umbraco.Core/DeliveryApi/NoopRequestMemberAccessService.cs
#	src/Umbraco.Core/Models/DeliveryApi/ProtectedAccess.cs
#	src/Umbraco.Core/Services/ITagService.cs
#	src/Umbraco.Core/Services/UserService.cs
#	src/Umbraco.Infrastructure/Security/IMemberApplicationManager.cs
#	src/Umbraco.Infrastructure/Security/OpenIdDictApplicationManagerBase.cs
#	src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
#	src/Umbraco.Web.BackOffice/Controllers/MediaController.cs
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/HelpPanel/systemInformation.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Login/login.spec.ts
#	version.json
2023-10-26 09:48:05 +02:00
Kenn JacobsenandGitHub b7a1cd5ab4 Cleaned up V14 TODOs from ContentApiItemControllerBase (#15026) 2023-10-24 10:08:28 +02:00
kjac 37082ac53d Remove duplicate reference to Core
(cherry picked from commit 304a64be5a)
2023-10-23 19:34:38 +02:00
Ronald Barendseandkjac ebc6e38b86 Ensure PackageVersion is set correctly before transforming template.json
(cherry picked from commit 0170ecaec1)
(cherry picked from commit 69c1bcec3a)
2023-10-23 19:34:30 +02:00
kjac e30a87d1fd Merge branch 'v13/dev' into v14/dev
# Conflicts:
#	Directory.Build.props
#	build/azure-pipelines.yml
#	src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs
#	src/Umbraco.Cms.Api.Common/OpenApi/SwaggerRouteTemplatePipelineFilter.cs
#	src/Umbraco.Cms.Api.Common/Security/Paths.cs
#	src/Umbraco.Cms.Api.Delivery/Controllers/Security/MemberController.cs
#	src/Umbraco.Cms.Api.Delivery/DependencyInjection/UmbracoBuilderExtensions.cs
#	src/Umbraco.Cms.Api.Delivery/Handlers/InitializeMemberApplicationNotificationHandler.cs
#	src/Umbraco.Cms.Api.Delivery/Handlers/RevokeMemberAuthenticationTokensNotificationHandler.cs
#	src/Umbraco.Cms.Api.Delivery/Security/MemberApplicationManager.cs
#	src/Umbraco.Cms.Api.Delivery/Services/RequestMemberAccessService.cs
#	src/Umbraco.Core/Constants-OAuthClaims.cs
#	src/Umbraco.Core/Constants-OAuthClientIds.cs
#	src/Umbraco.Core/DeliveryApi/IApiContentQueryProvider.cs
#	src/Umbraco.Core/DeliveryApi/IApiContentQueryService.cs
#	src/Umbraco.Core/DeliveryApi/IRequestMemberAccessService.cs
#	src/Umbraco.Core/DeliveryApi/NoopRequestMemberAccessService.cs
#	src/Umbraco.Core/Models/DeliveryApi/ProtectedAccess.cs
#	src/Umbraco.Core/Services/ITagService.cs
#	src/Umbraco.Core/Services/UserService.cs
#	src/Umbraco.Infrastructure/Security/IMemberApplicationManager.cs
#	src/Umbraco.Infrastructure/Security/OpenIdDictApplicationManagerBase.cs
#	src/Umbraco.Web.BackOffice/Controllers/MediaController.cs
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/HelpPanel/systemInformation.spec.ts
#	version.json
2023-10-23 19:03:13 +02:00
Andreas ZerbstandGitHub ace8d80183 Refactored from ISystemClock to TimeProvider (#14963)
* Removed obsolete ISystemClock. The SecurityStampValidator provides the TimeProvider.

* Removed obsolete ISystemClock.

* Refactored obsolete ISystemClock with TimeProvider
2023-10-12 13:58:51 +02:00
6fb2550690 V14/feature/response model trash tracking (#14948)
* Clearify UmbracoMapper functionality trough comment

* Add trash tracking to doc/media(item) response models

* Add mapping for ITracksTrashing

* Removed uneccesary abstraction and seperation

* Cleanup after removing abstractions

* Cleanup unused DI item

* Clean up and formatting

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: kjac <kja@umbraco.dk>
2023-10-12 07:00:06 +02:00
Elitsa MarinovskaandGitHub 517e0e9d19 Removing dev certificates and adding enc and signing keys that are required by OpenIddict but won't be used when we calling UseDataProtection() (#14958) 2023-10-11 14:15:08 +02:00
Nikolaj GeisleandGitHub 443f03688e Fix update to update foreach Group (#14945) 2023-10-11 10:46:25 +02:00
Mads RasmussenandGitHub 332ef6fa7e align user import map (#14952) 2023-10-11 10:01:22 +02:00
Bjarke Berg 838fd95f41 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	tests/Umbraco.Tests.AcceptanceTest/package-lock.json
#	tests/Umbraco.Tests.AcceptanceTest/package.json
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Content/blockGridEditorAdvanced.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Content/blockGridEditorAreasContent.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Content/blockGridEditorSettings.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Datatype/BlockGridEditorDataTypeBlocks.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockListEditor/blockListEditorDocument.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/content.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/routing.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/partialViews.spec.ts
2023-10-10 13:47:18 +02:00
Jacob Overgaard 7995df6cfd update backoffice submodule 2023-10-09 17:33:53 +02:00
Mads RasmussenandGitHub 99a1aa9301 update event path in importmap (#14844) 2023-10-09 16:15:40 +02:00
Jacob Overgaard 5b57234b52 update backoffice submodule 2023-10-06 12:04:21 +02:00
Mads RasmussenandGitHub ded1cbb9fa update import map to repository module (#14845) 2023-10-06 12:03:45 +02:00
Kenn JacobsenandGitHub 05522010d8 Default value editors for all (meaningful) value types (#14928)
* Expose editor UI alias in published property type, so custom value converters can use it

* Add default property value converters for all value types (#14869)

* Add default property value converters for all value types

* Clean up some left-over stuff

(cherry picked from commit ce86abe8ac)

* Added "plain" property editors for all (meaningful) value types
2023-10-06 10:42:23 +02:00
Jacob Overgaard 5c63561629 update backoffice submodule 2023-09-28 12:41:29 +02:00
83321a8fad Add member auth to the Delivery API (#14730)
* Refactor OpenIddict for shared usage between APIs + implement member authentication and handling within the Delivery API

* Make SwaggerRouteTemplatePipelineFilter UI config overridable

* Enable token revocation + rename logout endpoint to signout

* Add default implementation of SwaggerGenOptions configuration for enabling Delivery API member auth in Swagger

* Correct notification handling when (un)protecting content

* Fixing integration test framework

* Cleanup test to not execute some composers twice

* Update paths to match docs

* Return Forbidden when a member is authorized but not allowed to access the requested resource

* Cleanup

* Rename RequestMemberService to RequestMemberAccessService

* Rename badly named variable

* Review comments

* Hide the auth controller from Swagger

* Remove semaphore

* Add security requirements for content API operations in Swagger

* Hide the back-office auth endpoints from Swagger

* Fix merge

* Update back-office API auth endpoint paths + add revoke and sign-out endpoints (as of now they do not exist, a separate task will fix that)

* Swap endpoint order to maintain backwards compat with the current login screen for new back-office (will be swapped back again to ensure correct .well-known endpoints, see FIXME comment)

* Make "items by IDs" endpoint support member auth

* Add 401 and 403 to "items by IDs" endpoint responses

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
Co-authored-by: Elitsa <elm@umbraco.dk>
2023-09-26 09:22:45 +02:00
Bjarke Berg 624f9a0508 Checkout submodule for v14 integration tests 2023-09-25 11:35:29 +02:00
Bjarke Berg c653dff3c0 Cleanup duplicate package references 2023-09-25 11:21:58 +02:00
Bjarke Berg d2410d5150 Bump version 2023-09-22 10:56:28 +02:00
Bjarke Berg 866ef1a886 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-09-22 10:56:05 +02:00
Bjarke Berg 3184bdf5a9 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-09-22 10:24:40 +02:00
b8f948785a Added necesary classes to define the StringPropertyEditor (#14769)
* Added necesary classes to define the StringPropertyEditor

* Removed unnecesary code, baseclass takes care of everything

* More cleanup and added a propertyValueConverter

* Upped the expected default dataEditors in tests by 1 since we added one.

* Fixed a bad undo action

* PR feedback Removed unnecesary code and simplified methods

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
2023-09-20 14:49:53 +02:00
Bjarke Berg 49c71b1989 Merge 2023-09-20 14:13:21 +02:00
Bjarke Berg 8050bb97af Merge remote-tracking branch 'origin/release/14.0' into v14/dev 2023-09-19 15:31:20 +02:00
Bjarke Berg 964e3b5797 Fixed test 2023-09-19 15:30:48 +02:00
Bjarke Berg c0e378cc41 fixed issue after minimal hosting model 2023-09-19 14:59:46 +02:00
Bjarke Berg 463068c07b Updated to latest .net and fixes small issues with installer after 2023-09-19 14:57:24 +02:00
Bjarke Berg 4f98b546c5 Merge branch 'release/14.0' into v14/dev 2023-09-19 14:53:27 +02:00
Bjarke Berg ac8663ea13 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-09-19 13:02:53 +02:00
Bjarke Berg e059ac2e5b Add missing ImportMap replacement 2023-09-19 10:55:10 +02:00
Bjarke Berg c4f5a2aca8 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-09-19 10:44:02 +02:00
Jacob Overgaard 4b918cbb3a update backoffice submodule 2023-09-15 14:06:43 +02:00
Kenn JacobsenandGitHub 981bf09325 Minor Management API changes from FE (#14804)
* Change document delete into move-to-recycle-bin

* Make it possible to supply an explicit ID when creating content and media

* Change media delete into move-to-recycle-bin

* Merge "allowed child content types" controllers into one + fixed a bug that allowed all types if none were defined

* Update OpenAPI JSON to reflect merged endpoints
2023-09-14 10:07:08 +02:00
Bjarke Berg 925b195e4c Updated submodule and fixed import map 2023-09-12 10:40:05 +02:00
Bjarke Berg 45abec6e88 Merge remote-tracking branch 'origin/v14/feature/front-end-importmap-update' into v14/dev
# Conflicts:
#	src/Umbraco.Cms.StaticAssets/umbraco/UmbracoBackOffice/Default.cshtml
#	src/Umbraco.Cms.StaticAssets/umbraco/UmbracoInstall/Index.cshtml
2023-09-12 10:35:53 +02:00
Bjarke Berg 8ca57c50c2 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-09-12 10:22:37 +02:00
Mads RasmussenandJacob Overgaard db98f88773 add culture module 2023-09-11 15:24:04 +02:00
Mads RasmussenandJacob Overgaard 622041fabc rename context module to app module 2023-09-11 15:23:45 +02:00
Jacob Overgaard 4e0f6a5696 update backoffice submodule 2023-09-08 13:58:26 +02:00
Niels LyngsøandJacob Overgaard 8cb0862142 append 3 more things to the import maps of C# 2023-09-08 13:49:13 +02:00
Jacob Overgaard 597b0a2be2 update submodule 2023-09-08 13:39:35 +02:00
Jacob Overgaard 420503fe40 bump to preview003 2023-09-08 13:39:11 +02:00
Niels Lyngsø ff0c2ef57c append 3 more things to the import maps of C# 2023-09-08 13:33:09 +02:00
Niels LyngsøandJacob Overgaard 10047c7ea8 update sub module 2023-09-08 10:08:04 +02:00
e4cc2a0550 Fix/in browser postman auth & editor config boolean serialization (#14739)
* Add in-browser postman callback url

* Added a jsonconverter for property editor configuration boolean values that are persisted as numbers and serialized as strings...

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
2023-09-04 14:24:37 +02:00
Bjarke Berg dede983941 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-09-04 10:50:18 +02:00
Bjarke Berg ffa664f217 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-09-04 10:45:50 +02:00
4f5fc0b8a1 Bulk delete functionality for management api (#14735)
* Bulk delete

* Bulk delete

* Added bulk delete user groups

* Clean

---------

Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-08-29 15:51:20 +02:00
Bjarke Berg a07d29b76a Merge remote-tracking branch 'origin/v14/dev' into v14/dev 2023-08-28 12:17:40 +02:00
Bjarke Berg 1b3f7afe20 Use the IFileStreamSecurityValidator in the temporary file service 2023-08-28 12:17:34 +02:00
b8af4bab7d User forgot password functionality for Management API (#14704)
* Added attribute filter to ensure a request is taking a minimum time to response

* Added functionality to management api to send forgot password emails and verify these + do the actual reset using the token

* Renamed UserKey to UserId and updated OpenApi.json

* Update src/Umbraco.Core/Services/IUserService.cs

Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com>

* Cleanup

* Renaming param

* Fixing send user username instead of email + wrong EmailTypes

* Fixed issue with forgot password functionality after reusing other functionality

* Rename prop

* Adding docs and renaming param

* Handle password validation return types

* More cleanup

---------

Co-authored-by: Elitsa <elm@umbraco.dk>
Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com>
2023-08-28 12:14:16 +02:00
Bjarke Berg 6fbf04592c Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	build/azure-pipelines.yml
#	src/Umbraco.Cms.Api.Delivery/Controllers/DeliveryApiControllerBase.cs
#	src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs
#	src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyValueEditor.cs
#	src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyValueEditor.cs
#	src/Umbraco.Web.BackOffice/Controllers/MediaController.cs
#	tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Packaging/PackageDataInstallationTests.cs
#	tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/LocalizationServiceTests.cs
2023-08-28 11:46:22 +02:00
Bjarke BergandGitHub b17a7689ab Fixed up the relation management api endpoints to use guids and paging (#14706)
* Fixed up the relation management api endpoints to use guids and paging

* Cleanup

* Updated OpenApi.json
2023-08-28 11:16:56 +02:00
f2d11e3095 Add content and media sorting to the Management API (#14712)
* Add content and media sorting to the Management API

* Rename "id" to "key" throughout the ContentEditingService

* Update Open API json file

* Use "key" instead of "id" in ContentEditingServiceBase

* Use "key" instead of "id" in IMediaEditingService and MediaEditingService

* Turn delegates into abstracts + fix bug that allowed deleting items outside of the recycle bin

* Use PUT instead of POST

* Update src/Umbraco.Core/Services/MediaEditingService.cs

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* Update src/Umbraco.Core/Services/MediaEditingService.cs

Co-authored-by: Bjarke Berg <mail@bergmania.dk>

* Update Open API JSON

---------

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-08-28 08:56:57 +02:00
Kenn JacobsenandGitHub a9d7f3cbbb Content type and media type container CRUD controllers and services (#14682)
* CRUD for content and media type folders + refactor data type folder CRUD controllers and services to match

* Correct response types + update OpenAPI JSON

* Review changes

* Review changes

* Update OpenAPI JSON after merge
2023-08-24 09:32:36 +02:00
Andreas ZerbstandGitHub 98bcf15373 Added missing scope (#14711) 2023-08-23 13:24:16 +02:00
Bjarke Berg 6f10517fc6 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	build/azure-pipelines.yml
2023-08-21 08:05:22 +02:00
0096addcb9 Content and media type CRUD controllers and services (#14665)
* Add GetAsync method

* Fix up delete document type controller

* Add scope to delete async

* Add some scaffolding

* Add create model

* Start working on validation

* Move validation to its own service

* Use GetAllAsync instead of GetAsync

* Add initial composition support

Still need to figure out some kinks

* Validate compositions when creating

* Add initial folder support

* Initial handling of generic properties

* Add operation status responses

* Move create operation into service

* Add first test

* Fix issued shown by test

* Ensure a specific key can be specified when creating

* Rename container id to container key

Let's try and be consistent

* Create basic composition test

* Ensure new property groups are created with the correct key

* Add test showing property type issue

* Fix property types not using the expected key.

* Validate against model fetched from content type service

Just to make sure nothing explodes on the round trip

* Make helper for creating create models

* Add helper for creating container

* Make helper methods simpler to use

* Add test for compositions using compositions

* Add more composition tests

* Fix bug allowing element types to be composed by non element types

* Remove validators

This can just be a part of the editing service

* Minor cleanup

* Ensure that multiple levels of inheritance is possible

* Ensure doctype cannot be used as both composition and inheritance on the same doctype

* Ensure no duplicate aliases from composition and that compositions exists

* Minor cleanup

* Address todos

* Add SaveAsync method

* Renamed some models

* Rename from DocumentType to ContentType

* Clarify ParentKey as being container only + untangle things a tiny bit

* Clean out another TODO (less duplicate code) + more tests

* Refactor for reuse across different content types + add media type editing service + unit tests

* Refactor in preparation for update handling

* More tests + fixed bugs found while testing

* Simplify things a bit

* Content type update + a lot of unit tests + some refactor + fix bugs found while testing

* Begin building presentation factories for mapping view models to editing models

* Use async save

* Mapping factories and some clean-up

* Rename Key to Id (ParentKey to ParentId)

* Fix slight typo

* Use editing service in document type controllers and introduce media type controllers

* Validate containers and align container aliases with the current backoffice

* Remove ParentId from response

* Fix scope handling in DeleteAsync

* Refactor ContentTypeSort

* A little renaming for clarity + safeguard against changes to inheritance

* Persist allowed content types

* Fix bad merge + update controller response annotations

* Update OpenAPI JSON

* Update src/Umbraco.Cms.Api.Management/Controllers/DocumentType/DocumentTypeControllerBase.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Fix review comments

* Update usage of MapCreateAsync to ValidateAndMapForCreationAsync

---------

Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-08-17 12:28:16 +02:00
a1f6531453 V14: Consistently refer to user key (#14685)
* Fixup UserService

* Fixup PartialViewService

* Fixup ScriptService

* Fixup StylesheetService

* Use keys with usergroups instead of IDs

* Fix missed instances of performingUser

* Fixup DataTypeFolderControllerBase

---------

Co-authored-by: kjac <kja@umbraco.dk>
2023-08-17 08:35:48 +02:00
Bjarke Berg fb3ead87b8 Post merge fixes 2023-08-15 11:18:10 +02:00
Bjarke Berg 822d57135e Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Cms.Persistence.EFCore/Composition/UmbracoEFCoreComposer.cs
#	src/Umbraco.Infrastructure/PropertyEditors/BlockEditorValues.cs
#	src/Umbraco.Web.UI.Docs/gulpfile.js
2023-08-15 11:14:00 +02:00
Jacob Overgaard 826ec6a94f update backoffice submodule 2023-08-11 15:38:23 +02:00
Jacob Overgaard f540fe59ed update backoffice submodule 2023-08-11 15:36:43 +02:00
Jacob Overgaard 6fcb67e319 bump to preview002 2023-08-09 10:21:13 +02:00
Jacob Overgaard 6ccf825c48 outcomment c# docs for now (they do not work with .NET 8) 2023-08-09 10:21:04 +02:00
Jacob Overgaard d1547ffe0b typo 2023-08-09 10:20:51 +02:00
Jacob Overgaard 9e9c299cf8 update backoffice preview002 2023-08-08 15:41:16 +02:00
Jacob Overgaard 7e25f1b55f update importmap 2023-08-08 15:37:46 +02:00
Bjarke Berg d9f528f3ae Post merge fixes 2023-08-08 12:19:29 +02:00
Bjarke Berg 2839131033 Merge remote-tracking branch 'origin/v13/dev' into v14/dev 2023-08-08 12:10:18 +02:00
Jacob Overgaard 9b26aec4c3 set default culture for backoffice 2023-08-08 09:54:54 +02:00
Jacob Overgaard 9274c3fad9 update backoffice submodule 2023-08-08 09:49:42 +02:00
Bjarke BergandGitHub 45033437a2 Updated all 404 and 500 responses to use problem details model (#14634)
* Updated all 404 and 500 responses to use problem details

* Updated OpenApi.json

* Add missing ProducesResponseType

* Updated OpenApi.json
2023-08-04 10:51:20 +02:00
Jacob Overgaard 7b78fe9ced update backoffice submodule 2023-08-02 17:04:02 +02:00
Bjarke Berg 254e471d9b post merge fixes 2023-08-02 10:27:39 +02:00
Bjarke Berg bd0f20f4e4 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Core/CompatibilitySuppressions.xml
#	src/Umbraco.Infrastructure/CompatibilitySuppressions.xml
#	src/Umbraco.Web.BackOffice/CompatibilitySuppressions.xml
#	src/Umbraco.Web.Common/CompatibilitySuppressions.xml
#	tests/Umbraco.Tests.Common/CompatibilitySuppressions.xml
#	tests/Umbraco.Tests.Integration/CompatibilitySuppressions.xml
2023-08-02 10:23:53 +02:00
Bjarke Berg 68475a97d6 Do not sign in user after install, like in v12 2023-07-31 14:02:48 +02:00
Bjarke Berg 42ffb3b7d8 Reimplement fix from v12 to allow newlines in invite email 2023-07-31 13:59:53 +02:00
Nikolaj Geisle ea3712fb96 Remove v10 fix, as it hopefully should not be relevant for 14 2023-07-25 11:56:46 +02:00
Nikolaj Geisle 2ecee0ca32 Merge branch 'v13/dev' into v14/dev 2023-07-25 11:44:03 +02:00
Jacob Overgaard 9e0344d85a update backoffice submodule 2023-07-24 10:45:34 +02:00
MoleandGitHub e1281afb71 Merge pull request #14589 from umbraco/v14/merge
V14/merge
2023-07-21 13:47:06 +02:00
nikolajlauridsen 7ed856ae8e Comment out richtext test
This should no longer be nececary in new backoffice
2023-07-21 12:21:56 +02:00
nikolajlauridsen 473c27213e Undo props changes 2023-07-21 11:38:15 +02:00
nikolajlauridsen 90598dce0b Re-add package validation skips 2023-07-21 11:28:35 +02:00
nikolajlauridsen a4c287f1e8 Try re-adding submodule 2023-07-21 11:14:52 +02:00
nikolajlauridsen 7753df40ce Merge v13/dev 2023-07-21 10:59:47 +02:00
Nikolaj GeisleandGitHub 963151a1c1 V14: Rename folder response model (#14576)
* Rename FolderResposneModel

* Update OpenApi.json
2023-07-19 13:54:17 +02:00
Elitsa MarinovskaandGitHub 036876f349 V14: Add authorization policies to new Backoffice API controllers - p1 (#14551)
* AuditLog policies

* DataType policies

* Dictionary policies

* Document controllers policies

* DocumentBlueprint controllers policies

* DocumentType controllers policies

* HealthCheck controllers policies

* Language controllers policies

* LogViewer controllers policies

* Media controllers policies

* MediaType controllers policies

* Member controllers policies

* MemberGroup controllers policies

* MemberType controllers policies

* ModelsBuilder controllers policies

* Package controllers policies

* PartialView controllers policies

* Profiling controllers policies

* PropertyType controllers policies

* RedirectUrlManagement controllers policies

* Relation controllers policies

* RelationType controllers policies

* Script controllers policies

* Stylesheet controllers policies

* Telemetry controllers policies

* Template controllers policies

* TrackedReference controllers policies

* Upgrade controllers policies

* User controllers policies

* UserGroup controllers policies

* Other controllers cleanup

* Moved CreatePolicies to its own Extensions class

* Added TreeAccessScripts and TreeAccessStylesheets policies

* Remove comments

* Forgotten "New" prefix

* Duplicate Auth Policy

* Removed comment since we are using reference tokens and this is no longer a problem

* Fix AdminUserEditsRequireAdmin auth policy to use a constant

* Revert change

* Revery UpgradeControllerBase attribute

* Removed AdminUserEditsRequireAdmin policy as it will be implemented later on

* Adding RequireAdminAccess policy for Upgrade controller

* Wrong claim type
2023-07-19 08:02:51 +02:00
Jacob Overgaard 33f926853b update backoffice submodule 2023-07-18 13:47:48 +02:00
MoleandGitHub d306a65bd4 V14: Fix pipelines (#14566)
* Try undoing inheritance change

Just to see if the issue stems from there

* Try specifying order again

* Log something

* Maybe it's a culture thing

* That wasn't it

* Maybe content deliver need to exist as an applicationPart

* Order found types

* Cleanup
2023-07-18 10:18:31 +02:00
b31c59d2a5 V14: refactor property editor aliases (#14536)
* Rename migrations folder to v14

* Add renaming migration

* Add missing namespace to migration in plan

* Rename Tiny to richtext

* Obsolete old TinyMce

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Elitsa <elm@umbraco.dk>
2023-07-14 15:31:09 +03:00
nikolajlauridsen f533d923d8 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
#	tests/Umbraco.Tests.AcceptanceTest/package-lock.json
#	tests/Umbraco.Tests.AcceptanceTest/package.json
#	tests/Umbraco.Tests.AcceptanceTest/playwright.config.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Content/blockGridEditorAdvanced.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Content/blockGridEditorAreasContent.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Content/blockGridEditorContent.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Content/blockGridEditorRendering.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Content/blockGridEditorSettings.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockListEditor/blockListEditorContent.spec.ts
#	version.json
2023-07-14 10:04:53 +02:00
e40f1839c4 V14: Refactor LogViewerService (#14511)
* Refactor GetPagedLogsAsync to not use ILogViewer

* Refactor GetPagedLogsAsync to not use ILogViewer

* Reorder using statements

* Introduce ILogViewerRepository

* Remove skip and take from repository

* Return IEnumerable instead of pagedModel

* Remove local GetLogs

* Return IEnumerable instead of pagedmodel

* Remove serilog entirely from ILogViewerService

* Move LogViewerService

* Inject LogViewerService as core service instead

* Implement LogViewerServiceTests.cs

* Add more happy path tests

* Add saved query tests

* Refactor private path fields  to normal variables in setup method

* Capitalize logs for Unix systems

* Added missing documentation

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Elitsa <elm@umbraco.dk>
2023-07-10 15:36:20 +03:00
Jacob Overgaard 82f79cafe8 update backoffice submodule 2023-07-10 11:22:37 +02:00
MoleandGitHub 578ced2778 Enable inheritance after merge (#14512)
* Enable inheritance after merge

* Update OpenApi.json
2023-07-10 10:13:46 +02:00
Jacob Overgaard 11dd958a33 update backoffice submodule 2023-07-07 15:49:40 +02:00
Bjarke Berg 47d5ef88c4 Post merge fixes - Including temp workaround for .net8 efcore breaking change (Should be fixed again in preview 7) 2023-07-07 10:55:29 +02:00
Bjarke Berg d991285466 Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts:
#	Directory.Build.props
#	src/Umbraco.Web.BackOffice/Controllers/MediaController.cs
2023-07-07 08:56:17 +02:00
c7a38cdac4 V14: Public access controller (#14501)
* Implement GetEntryByContentKey

* Implement PublicAccessResponseModel

* Implement IPublicAccessPresentationFactory

* Rename MemberGroupItemReponseModel to MemberGroupItemResponseModel

* Refactor PublicAccessResponseModel to use Ids instead of entire content items

* Return attempt instead of PresentationModel

* Add missing statuses to PublicAccessOperationStatusResult

* Implement PublicAccessDocumentController.cs

* Refacotr PublicAccessResponseModel to use a base model

* Add CreatePublicAccessEntry method

* Refactor AccessRequestModel to use names not ids :(

* Rename ErrorPageNotFound to ErrorNodeNotFound

* Implement new SaveAsync method

* Introduce more OperationResults

* Implement PublicAccessEntrySlim

* Implement SaveAsync

* Remove CreatePublicAccessEntry from presentation factory

* Rename to CreateAsync

* Implement UpdateAsync

* Rename to async

* Implement CreatePublicAccessEntry

* Implement update endpoint

* remove PublicAccessEntrySlim mapping

* implement CreatePublicAccessEntrySlim method

* Refactor UpdateAsync

* Remove ContentId from request model as it should be in the request

* Use new service layer

* Amend method name in update controller

* Refactor create public access entry to use async method and return entity

* Refactor to use saveAsync method instead of synchronously

* Use presentation factory instead of mapping

* Implement deleteAsync endpoint

* Add produces response type

* Refactor mapping to not use UmbracoMapper, as that causes errors

* Update OpenApi.json

* Refactor out variables to intermediate object

* Validate that groups and names are not specified at the same time

* Make presentation factory not async

* Minor cleanup

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-07-05 14:56:51 +02:00
ed83b65de3 V14: Refactor icons for tree items (#14477)
* Remove icons from base models

* Update OpenApi spec

* Updated schema

* Cleanup

* Fix Response Type

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Elitsa <elm@umbraco.dk>
2023-07-05 15:09:39 +03:00
59df7439db Verify user invite token (#14491)
* Added functionality to verify user invite tokens and create the initial password

* Add response types

* Fail ValidateCredentialsAsync when user is not approved

* Enable user as part of initial password creating using validation token

* Adds documentation to badrequest and changed nocontent to ok, to align with other APIs

* Fixed tests and added a new one

---------

Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch>
2023-07-05 12:42:52 +02:00
Jacob Overgaard 8bccab3b60 update backoffice submodule 2023-07-03 14:14:09 +02:00
Kenn JacobsenandGitHub 0496fba70b Fix EFCore.Sqlite and EFCore.SqlServer project load in solution file (#14480) 2023-06-29 18:36:29 +02:00
Jacob Overgaard 113b1ff216 update backoffice submodule 2023-06-29 14:12:52 +02:00
Elitsa MarinovskaandGitHub cdfae0ce0b V14: Skip and take updates (#14478)
* Adding default values to skip and take to align with the rest of the controllers

* Changing skip and take type from long to int to align with the rest

* Fixing wrong response type

* Remove double skip and take

* Update json file
2023-06-29 12:33:31 +02:00
d5a0dda89a V14: allowed children endpoints (#14434)
* Implement allowed children of root

* Allow children by key controller

* Update to be document controlller instead

* Fix AllowedChildrenOfRootDocumentController

* Create GetAllAsync method in ContentTypeServiceBaseOfTRepositoryTItemTService

* Revert "Create GetAllAsync method in ContentTypeServiceBaseOfTRepositoryTItemTService"

This reverts commit b01b5b9240.

* Implement attemp pattern in IContentTypeService

* Create IContentCreatingService

* Use new contentCreatingService in controller

* Revert if statement

* Use total from attempt

* Throw exceptions instead of returning attempt

* Wrap in scope

* Rename to GetAllowedChildrenContentTypesAsync

* Fix summary

* Removed unneccessary await Task.FromResult

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-06-29 09:38:05 +02:00
Andreas ZerbstandGitHub 85ad419cb7 Updated our API acceptance tests to use our updated testHelpers (#14476)
* Updated our dataType API tests to use our updated testHelpers

* Updated our dataTypeFolder API tests to use our updated testHelpers

* Updated our dictionary API tests to use our updated testHelpers

* Updated our language API tests to use our updated testHelpers

* Updated our partialView API tests to use our updated testHelpers

* Updated our partialViewFolder API tests to use our updated testHelpers

* Updated our script API tests to use our updated testHelpers

* Updated our scriptFolder API tests to use our updated testHelpers

* Updated our stylesheet API tests to use our updated testHelpers

* Updated our stylesheetFolder API tests to use our updated testHelpers

* Updated our telemetry API tests to use our updated testHelpers

* Updated our template API tests to use our updated testHelpers

* Updated our temporaryFile API tests to use our updated testHelpers

* Updated our user API tests to use our updated testHelpers

* Updated our userAvatar API tests to use our updated testHelpers

* Updated our userGroup API tests to use our updated testHelpers

* Fixed failing text

* Bumped to use the newest version of our testHelpers
2023-06-29 07:16:33 +02:00
ddca33337b v14: Rewrite static assets for the backoffice (#14472)
* add extension method to rewrite requests meant for backoffice static assets

* add backoffice rewrites to application builder

* embed the umbraco hash into the static assets requested on the backoffice

* Added a IStaticFileHostGenerator so its possible to replace our logic

* add docs and ensure the path is uniform with single slashes

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-06-28 14:55:19 +02:00
7265d5c3be Use OpenIddict with real db instead of inmemory (#14465)
* Add OpenIddict tables to database (#14449)

* Added migrations to install EF Core OpenIddict tables

* Handle Install of ef core data (Needs to be outside of transaction

* Cleanup and renaming, as these things will be reused for more than openiddict in the future

* Cleanup

* Extract db context setup

* Minor cleanup

---------

Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>

* Use OpenIddict from DB instead of InMemoryDb

* Do not try to clean up, while not it run mode

* Fixed tests

* Clean up

---------

Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
Co-authored-by: Elitsa <elm@umbraco.dk>
2023-06-28 09:40:28 +03:00
dfc7054720 V14: refactor GetPermissions to use attempt pattern (#14470)
* Refactor GetPermissions to take params

* Rework GetPermissionsAsync to attempt pattern

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
2023-06-27 14:34:02 +02:00
Bjarke Berg 135a43f5a4 Add Microsoft.EntityFrameworkCore.Design to UI.New 2023-06-27 10:20:19 +02:00
Jacob Overgaard 44a3d86986 package-lock sync 2023-06-27 10:03:04 +02:00
Jacob Overgaard 8bb43a8eda Merge branch 'v13/dev' into v14/dev 2023-06-27 10:02:46 +02:00
Jacob Overgaard 2511be61cc package-lock sync 2023-06-27 10:01:45 +02:00
Bjarke Berg 4aa7001fbf Merge remote-tracking branch 'origin/v12/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Core/Services/ContentService.cs
#	src/Umbraco.Infrastructure/CompatibilitySuppressions.xml
#	src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
#	src/Umbraco.Web.BackOffice/Controllers/MediaController.cs
2023-06-27 09:50:37 +02:00
Andreas ZerbstandGitHub de235c224a Added missing scope (#14460) 2023-06-26 16:43:22 +02:00
Andreas ZerbstandGitHub 437db52e5e Added UI acceptance for the telemetry section (#14456)
* Added auth to gitignore

* Added a setup for logging in which allows us to save the token for the user

* Added simple acceptance test for testing our api for the DataTypes

* Added simple acceptance tests for testing the API for the PartialView section

* Added simple acceptance tests for testing the API for the Script section

* Added acceptance tests for testing the API for the Stylesheet section.

* Added acceptance tests for testing the API for the User section

* Bumped the version of our testhelpers!

* Added acceptance tests for testing the API for the Dictionary section.

* Added acceptance tests for testing the API for the Language section.

* Added acceptance tests for testing the API for the UserGroups section.

* Added acceptance tests for testing the API for the Template section

* Added acceptance tests for testing the API for the TemporaryFiles section

* Our first UI test for v14

Added acceptance tests for the telemetry section

* Removed page.pause
2023-06-26 15:05:50 +02:00
Andreas ZerbstandGitHub acf8f575a8 Added acceptance tests for testing the API for the UserGroups section. (#14448)
* Added auth to gitignore

* Added a setup for logging in which allows us to save the token for the user

* Added simple acceptance test for testing our api for the DataTypes

* Added simple acceptance tests for testing the API for the PartialView section

* Added simple acceptance tests for testing the API for the Script section

* Added acceptance tests for testing the API for the Stylesheet section.

* Added acceptance tests for testing the API for the User section

* Bumped the version of our testhelpers!

* Added acceptance tests for testing the API for the Dictionary section.

* Added acceptance tests for testing the API for the Language section.

* Added acceptance tests for testing the API for the UserGroups section.

* Added acceptance tests for testing the API for the Template section (#14450)

* Added acceptance tests for testing the API for the Template section

* Added acceptance tests for testing the API for the TemporaryFiles section (#14451)
2023-06-26 13:09:41 +02:00
Andreas ZerbstandGitHub ad419dd460 Added acceptance tests for testing the API for the Language section. (#14447)
* Added auth to gitignore

* Added a setup for logging in which allows us to save the token for the user

* Added simple acceptance test for testing our api for the DataTypes

* Added simple acceptance tests for testing the API for the PartialView section

* Added simple acceptance tests for testing the API for the Script section

* Added acceptance tests for testing the API for the Stylesheet section.

* Added acceptance tests for testing the API for the User section

* Bumped the version of our testhelpers!

* Added acceptance tests for testing the API for the Dictionary section.

* Added acceptance tests for testing the API for the Language section.
2023-06-26 12:23:01 +02:00
Andreas ZerbstandGitHub fbc8d453e3 Added acceptance tests for testing the API for the Dictionary section. (#14446)
* Added auth to gitignore

* Added a setup for logging in which allows us to save the token for the user

* Added simple acceptance test for testing our api for the DataTypes

* Added simple acceptance tests for testing the API for the PartialView section

* Added simple acceptance tests for testing the API for the Script section

* Added acceptance tests for testing the API for the Stylesheet section.

* Added acceptance tests for testing the API for the User section

* Bumped the version of our testhelpers!

* Added acceptance tests for testing the API for the Dictionary section.
2023-06-26 12:21:09 +02:00
Jacob Overgaard ca6f9ffadb Merge remote-tracking branch 'origin/v14/dev' into v14/dev 2023-06-26 10:19:46 +02:00
Jacob Overgaard 7a8c4af161 update backoffice submodule 2023-06-26 10:19:38 +02:00
Andreas ZerbstandGitHub b0b29f05af Added acceptance tests for testing the API for the Users section. (#14445)
* Added auth to gitignore

* Added a setup for logging in which allows us to save the token for the user

* Added simple acceptance test for testing our api for the DataTypes

* Added simple acceptance tests for testing the API for the PartialView section

* Added simple acceptance tests for testing the API for the Script section

* Added acceptance tests for testing the API for the Stylesheet section.

* Added acceptance tests for testing the API for the User section

* Bumped the version of our testhelpers!
2023-06-26 10:13:36 +02:00
Andreas ZerbstandGitHub 87a66c064f Added acceptance tests for testing the API for the Script section (#14441)
* Added auth to gitignore

* Added a setup for logging in which allows us to save the token for the user

* Added simple acceptance test for testing our api for the DataTypes

* Added simple acceptance tests for testing the API for the PartialView section

* Added simple acceptance tests for testing the API for the Script section

* Added acceptance tests for testing the API for the Stylesheet section. (#14442)
2023-06-23 12:00:16 +02:00
Andreas ZerbstandGitHub ea520cb851 Added acceptance tests for testing the API for the PartialView section (#14438)
* Added auth to gitignore

* Added a setup for logging in which allows us to save the token for the user

* Added simple acceptance test for testing our api for the DataTypes

* Added simple acceptance tests for testing the API for the PartialView section
2023-06-23 11:09:47 +02:00
Andreas ZerbstandGitHub 893e00f100 Added acceptance test for testing our api for the DataTypes section (#14437)
* Added auth to gitignore

* Added a setup for logging in which allows us to save the token for the user

* Added simple acceptance test for testing our api for the DataTypes
2023-06-23 10:32:17 +02:00
Andreas ZerbstandGitHub 1d215aa1b1 V14/qa/new acceptance tests (#14435)
* Added auth to gitignore

* Added a setup for logging in which allows us to save the token for the user
2023-06-23 08:56:30 +02:00
Bjarke Berg 1149cddc09 Update openAPI 2023-06-22 12:46:25 +02:00
Bjarke Berg 053f2e6dff Merge remote-tracking branch 'origin/v12/dev' into v14/dev 2023-06-22 11:37:44 +02:00
Bjarke Berg b7df9f2357 Post merge, add missing swagger UI options 2023-06-22 11:28:22 +02:00
Bjarke Berg 4f93542909 Updated OpenApi.json 2023-06-21 10:18:36 +02:00
Bjarke Berg 37d8513b42 Remove wrong obsolete message that have been merged up 2023-06-21 09:14:55 +02:00
Bjarke Berg 2ed2fc3533 Added TrustServerCertificate to install apis 2023-06-21 09:12:00 +02:00
Bjarke Berg 22b2f79d15 Merge remote-tracking branch 'origin/v12/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderApiExtensions.cs
#	src/Umbraco.Core/CompatibilitySuppressions.xml
#	src/Umbraco.Infrastructure/CompatibilitySuppressions.xml
#	src/Umbraco.Web.Common/Profiler/WebProfiler.cs
2023-06-21 09:06:42 +02:00
Bjarke Berg 7a4a4f60c4 Merge remote-tracking branch 'origin/release/14.0' into v14/dev 2023-06-21 09:05:31 +02:00
Jacob Overgaard 95f7cdd418 add dependency on 'Build' stage to get output parameter 2023-06-20 13:56:45 +02:00
dependabot[bot]andJacob Overgaard 8d6d933600 Bump socket.io-parser from 4.2.1 to 4.2.4 in /src/Umbraco.Web.UI.Client
Bumps [socket.io-parser](https://github.com/socketio/socket.io-parser) from 4.2.1 to 4.2.4.
- [Release notes](https://github.com/socketio/socket.io-parser/releases)
- [Changelog](https://github.com/socketio/socket.io-parser/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io-parser/compare/4.2.1...4.2.4)

---
updated-dependencies:
- dependency-name: socket.io-parser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-20 13:30:43 +02:00
dependabot[bot]andJacob Overgaard 0fa42a10b5 Bump socket.io-parser from 4.2.1 to 4.2.4 in /src/Umbraco.Web.UI.Client
Bumps [socket.io-parser](https://github.com/socketio/socket.io-parser) from 4.2.1 to 4.2.4.
- [Release notes](https://github.com/socketio/socket.io-parser/releases)
- [Changelog](https://github.com/socketio/socket.io-parser/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io-parser/compare/4.2.1...4.2.4)

---
updated-dependencies:
- dependency-name: socket.io-parser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-20 13:30:31 +02:00
dependabot[bot]andJacob Overgaard 8622344b96 Bump fast-xml-parser and is-svg in /src/Umbraco.Web.UI.Client
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) and [is-svg](https://github.com/sindresorhus/is-svg). These dependencies needed to be updated together.

Updates `fast-xml-parser` from 3.20.3 to 4.2.4
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/commits)

Updates `is-svg` from 4.3.1 to 4.4.0
- [Release notes](https://github.com/sindresorhus/is-svg/releases)
- [Commits](https://github.com/sindresorhus/is-svg/compare/v4.3.1...v4.4.0)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-type: indirect
- dependency-name: is-svg
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-20 13:24:20 +02:00
dependabot[bot]andJacob Overgaard c665ab453d Bump fast-xml-parser and is-svg in /src/Umbraco.Web.UI.Client
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) and [is-svg](https://github.com/sindresorhus/is-svg). These dependencies needed to be updated together.

Updates `fast-xml-parser` from 3.20.3 to 4.2.4
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/commits)

Updates `is-svg` from 4.3.1 to 4.4.0
- [Release notes](https://github.com/sindresorhus/is-svg/releases)
- [Commits](https://github.com/sindresorhus/is-svg/compare/v4.3.1...v4.4.0)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-type: indirect
- dependency-name: is-svg
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-20 13:24:13 +02:00
Jacob Overgaard b4ab76c2a8 update backoffice submodule 2023-06-20 13:17:26 +02:00
Jacob Overgaard 2cb1d31375 Merge branch 'v14/dev' of https://github.com/umbraco/Umbraco-CMS into v14/dev 2023-06-20 11:02:41 +02:00
Jacob Overgaard 645345a51b v11: Backoffice JS Updates (#14407)
* update @umbraco-ui/uui to 1.3.0

* update @microsoft/signalr to 7.0.7

* update ace editor to 1.22.1

* update jQuery to 3.7.0

* update nouislider to 15.7.1

* update tinymce to 6.5.1

* update spectrum-colorpicker2 to 2.0.10

* update build dependencies
2023-06-20 11:02:32 +02:00
Jacob Overgaard 43fb128292 v11: Backoffice JS Updates (#14407)
* update @umbraco-ui/uui to 1.3.0

* update @microsoft/signalr to 7.0.7

* update ace editor to 1.22.1

* update jQuery to 3.7.0

* update nouislider to 15.7.1

* update tinymce to 6.5.1

* update spectrum-colorpicker2 to 2.0.10

* update build dependencies
2023-06-20 11:02:20 +02:00
MoleandGitHub dd90ef2d81 Update OpenApi.json (#14417) 2023-06-20 10:23:41 +02:00
Jacob OvergaardandGitHub 5900f5bede v14: update package templates with new umbraco-package.json format (#14412)
* update package templates with new umbraco-package.json format

* remove $schema for now because we dont know where people will locate this file (refer to documentation)
2023-06-19 15:29:27 +02:00
Jacob Overgaard a463415b47 update backoffice submodule 2023-06-19 14:47:32 +02:00
Jacob Overgaard c512039083 upload api docs after myget release 2023-06-13 12:52:16 +02:00
Jacob Overgaard 3ed89c9a6d Merge branch 'v14/dev' into release/14.0 2023-06-13 12:50:14 +02:00
Jacob Overgaard 2c3c86a55d update backoffice submodule 2023-06-13 12:49:45 +02:00
Jacob Overgaard 0fcb2890aa Merge remote-tracking branch 'origin/v14/dev' into release/14.0 2023-06-12 14:20:51 +02:00
Jacob Overgaard d9c1de928b update backoffice submodule 2023-06-12 14:17:06 +02:00
Jacob OvergaardandGitHub da0ad33818 V14: frontend ui docs (#14374)
* update script to compile frontend api docs

* update backoffice submodule

* set the base path for the ui docs

* update env syntax

* remove Umbraco.Web.UI.Docs

* replace BASE_PATH in assets

* Make Upload API step able to run without releasing on nuget

* add dependOn Build to get major version number
2023-06-12 14:12:02 +02:00
Bjarke Berg 520309e3f8 Merge remote-tracking branch 'origin/v12/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
#	src/Umbraco.Infrastructure/Persistence/Repositories/Implement/UserRepository.cs
#	src/Umbraco.Web.BackOffice/Controllers/MediaController.cs
#	src/Umbraco.Web.BackOffice/Filters/FileUploadCleanupFilterAttribute.cs
2023-06-12 10:10:08 +02:00
Jacob Overgaard 1e95437a0a update backoffice submodule 2023-06-09 11:18:38 +02:00
MoleandGitHub 64c7c6b439 Fetch GUID directly and make it non async (#14358) 2023-06-08 14:49:52 +02:00
MoleandGitHub 040bf2c1e3 Replace use of SortedSet with HashSets and ISets (#14353) 2023-06-08 10:30:23 +02:00
Bjarke Berg 9a8edbabb3 Merge remote-tracking branch 'origin/v12/dev' into v14/dev 2023-06-08 10:12:10 +02:00
Bjarke Berg 63b1865053 Merge remote-tracking branch 'origin/release/14.0' into v14/dev 2023-06-08 10:12:02 +02:00
Bjarke Berg c84a3e2fe4 Merge remote-tracking branch 'origin/v12/dev' into release/14.0
# Conflicts:
#	src/Umbraco.Core/Manifest/PackageManifest.cs
#	src/Umbraco.Core/Telemetry/TelemetryService.cs
#	src/Umbraco.Infrastructure/Manifest/LegacyManifestParser.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/V_12_0_0/ResetCache.cs
#	src/Umbraco.Infrastructure/Persistence/Repositories/Implement/CreatedPackageSchemaRepository.cs
#	src/Umbraco.Infrastructure/Services/Implement/PackagingService.cs
#	tests/Umbraco.Tests.UnitTests/Umbraco.Core/Telemetry/TelemetryServiceTests.cs
2023-06-08 10:07:29 +02:00
MoleandGitHub fdf5beb22a Add get ByEditorUiAlias datatype item endpoint (#14352) 2023-06-08 09:04:48 +02:00
Bjarke Berg 498eb083dd Updated version number 2023-06-07 16:12:47 +02:00
Niels LyngsøandGitHub fe714805bb Add location header for CORS requests (#14349) 2023-06-07 10:15:16 +02:00
MoleandGitHub 582b784ffe V14: Update template controllers (#14326)
* Add alias to document item response

* Add master template key to detailed model

* Add mater template key as optiona parameter to Scaffolding

* Check for duplicate alias when creating templates directly

* Clean

* Ensure integration tests creates templates with unique aliases

* Perform mapping in presentation factory
2023-06-06 13:45:39 +02:00
Jacob Overgaard 9947d4a15a update backoffice submodule 2023-06-06 10:44:18 +02:00
Kenn JacobsenandGitHub fe0cbc50c8 Temporary CRUD API for content types (#14334)
* Add temporary controllers for document type CRUD

* Update OpenAPI json

* Review comments

* Add comment for future refactoring
2023-06-06 09:32:02 +02:00
4180170acf Get current user endpoint in management api (#14336)
* Add current user data endpoint

* Add Change password endpoint

* Add SetAvatar

* Add get node permissions

* Add endpoint for getting currently logged in users linked logins

* Add tour service

* Add get tours

* Add set tour endpoint

* Added PermissionNames to IReadOnlyUserGroup

* Only require backend auth on management api

* Use ISet in response model

* Fixed issue with saving null as startMediaId, where it was ignored

* Add get current user endpoint

* Fix missing linebreak

* Append "New" keyword to policies

* Update OpenApi

---------

Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-06-05 15:20:18 +02:00
MoleandGitHub 0ad0179cd6 V14: Current user controller (#14323)
* Add current user data endpoint

* Add Change password endpoint

* Add SetAvatar

* Add get node permissions

* Add endpoint for getting currently logged in users linked logins

* Add tour service

* Add get tours

* Add set tour endpoint

* Split permissions endpoint in two, one for media and one for document
2023-06-05 08:42:29 +02:00
Jacob Overgaard 4a07f9a839 update backoffice submodule 2023-06-02 12:08:34 +02:00
Jacob Overgaard ef0e085c74 add login build to azure 2023-06-02 11:46:47 +02:00
Jacob Overgaard 6c731ca4ec update backoffice submodule 2023-06-02 11:23:01 +02:00
Jacob Overgaard 1e76ace11a add asp-append-version to static assets for backoffice 2023-06-01 11:29:10 +02:00
Jacob Overgaard 7839e14163 update backoffice submodule 2023-06-01 08:52:01 +02:00
Jacob OvergaardandGitHub 43ffeb673b v14: login app (#14318)
* ignore output files

* add new umb-login element

* allow to build and clean 'login' assets

* remove unused AuthUrl since this is now coded into the frontend code for each context

* ensure the ReturnUrl has a fallback to the default installation directory, since if you accidentally hit the login page and login, nothing happens if there is no return url

* switch to DependsOnTargets to account for if this is the only target being run (we need node_modules installed)

* add UmbracoUrl property

* add taghelper to use asp-append-version on login static assets
2023-06-01 08:50:21 +02:00
Jacob OvergaardandGitHub 33cb74dff1 V14: umbraco-package.json schema (#14319)
* copy umbraco-package-schema.json over from the New.Client build

* when a project referencing Cms.Targets is  building, we want to copy out the umbraco-package-schema.json file to the project directory if it does not exist

* ignore built output files

* fix typo

* add PackageReference to Umbraco.Cms.Targets to ensure dependent json schema files are copied over

* add to gitignore

* add target to remove the _UmbracoCmsPackageSchemaReference on clean

* Revert "add PackageReference to Umbraco.Cms.Targets to ensure dependent json schema files are copied over"

This reverts commit 339043a36f.

* generate umbraco-package-schema.json on demand in Cms.Targets

* add generated file to .gitignore
2023-05-31 19:12:00 +02:00
Jacob Overgaard cdd3adfd3c update backoffice submodule 2023-05-31 14:41:23 +02:00
Bjarke Berg dbfedf31bd Merge remote-tracking branch 'origin/v12/dev' into v14/dev 2023-05-31 09:46:59 +02:00
Jacob Overgaard 61c4aac0c9 update backoffice submodule 2023-05-30 16:10:56 +02:00
Jacob Overgaard 917b227294 update backoffice submodule 2023-05-30 14:13:23 +02:00
MoleandGitHub 138148481d V14: Add information to tree items (#14301)
* Add variant information to the document tree model

* Add content type key to document tree and item

* Add sort order to PropertyTypeResponseModelBase
2023-05-30 11:00:22 +02:00
Jacob Overgaard 3c3ab83411 update backoffice submodule 2023-05-26 16:10:36 +02:00
Jacob Overgaard 2d7a62eac5 update backoffice submodule 2023-05-26 11:22:59 +02:00
Bjarke Berg b9c0e18fb1 Merge remote-tracking branch 'origin/v12/dev' into v14/dev
# Conflicts:
#	src/Umbraco.Cms.Api.Delivery/Services/ApiContentQueryService.cs
#	src/Umbraco.Core/CompatibilitySuppressions.xml
#	src/Umbraco.Core/DeliveryApi/IApiContentQueryProvider.cs
#	src/Umbraco.Core/DeliveryApi/IApiContentQueryService.cs
#	src/Umbraco.Core/DeliveryApi/NoopApiContentQueryService.cs
2023-05-25 14:51:28 +02:00
Bjarke Berg 32b3b3b4a0 Updated version number 2023-05-25 13:35:11 +02:00
Bjarke Berg e04bb9d18d Fix tests by updating OpenApi.json 2023-05-25 12:34:26 +02:00
Jacob Overgaard b245f319d9 update backoffice submodule 2023-05-25 11:20:16 +02:00
Bjarke Berg 803e1be7dd Add PKCE to swagger.. Missing after refactor 2023-05-25 11:04:02 +02:00
Bjarke Berg b5ed4ea43a Rename the security definition as this is only for users.. 2023-05-25 11:03:56 +02:00
Bjarke BergandGitHub 28712bd5cd Make new backoffice packable (#14286)
* This moves around files and deletes the temp projects with files that are not moved to Core, Infrastructure etc.

Also moves the from new backoffice to static access, and override those with the old views in the legacy executeable

* Removes old files from the new executeable.

* Added missing files

* Added EF Core project to solution file

* fix build
2023-05-25 10:38:44 +02:00
714cf374f0 Management API: Property editor temporary file handling (#14244)
* Use new temporary files handling for property editors

* Add compat suppressions

* Add missing compat suppressions

* Don't discard valid file upload values

* Rename cuid and puid to contentKey and propertyTypeKey

* Update src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Fetch user async + remove unnecessary dependency

---------

Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch>
2023-05-24 12:31:19 +02:00
Jacob Overgaard fc0e2cbf00 update backoffice submodule 2023-05-23 13:08:56 +02:00
Bjarke Berg b4e7d55e4d Align versions 2023-05-23 12:29:56 +02:00
Bjarke Berg 8f5f7f72fa Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	version.json
2023-05-23 12:23:27 +02:00
Jacob Overgaard 38aacfc30a update backoffice submodule 2023-05-22 13:27:56 +02:00
Jacob Overgaard c5f1af8adc update backoffice submodule 2023-05-17 11:11:37 +02:00
Andreas ZerbstandGitHub ac0f76f162 Changed so we are checking if the FolderExits (#14196) 2023-05-15 09:05:22 +02:00
Bjarke Berg f2def5307c Fix build 2023-05-15 09:02:53 +02:00
Bjarke Berg 979e023d73 Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	src/Umbraco.Infrastructure/CompatibilitySuppressions.xml
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Content/blockGridEditorAdvanced.spec.ts
2023-05-15 08:51:50 +02:00
Bjarke Berg ebbd3f0e51 Compatibility files 2023-05-12 12:33:03 +02:00
Bjarke Berg 2922c1fc92 Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderApiExtensions.cs
#	src/Umbraco.Cms.Api.Delivery/Controllers/DeliveryApiControllerBase.cs
#	src/Umbraco.Core/CompatibilitySuppressions.xml
#	src/Umbraco.Web.Common/Configuration/ConfigureApiVersioningOptions.cs
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Tabs/tabs.spec.ts
2023-05-12 11:42:15 +02:00
Jacob Overgaard efe03d328a update backoffice submodule 2023-05-11 10:00:10 +02:00
MoleandGitHub f615e7bcfc Only consider alias duplicate if the key matches (#14169) 2023-05-09 10:46:31 +02:00
Bjarke Berg 0391c1d0c7 Merge remote-tracking branch 'origin/v13/dev' into v13/dev
# Conflicts:
#	src/Umbraco.Cms.Api.Common/Configuration/ConfigureApiExplorerOptions.cs
2023-05-09 09:21:36 +02:00
Bjarke Berg 5dd945f372 Reintroduced management api after v12 merge 2023-05-09 09:21:16 +02:00
Bjarke BergandGitHub 417e92dad0 Updated API version package and moved attribute to each controller (#14209)
* Updated API version package and moved attribute to each controller as it cannot be inherited.

* Ignore "$type" on types implementing interfaces in the delivery api
2023-05-09 08:38:07 +02:00
Bjarke Berg 6ce895e9ac Cherry picked removal of management api and rolled back. 2023-05-08 17:44:44 +02:00
Bjarke Berg 839999e76f Ensure no management api for v12 (#14197)
* Remove management api

* Remove actual files

And rolled both back again
2023-05-08 17:42:43 +02:00
Jacob Overgaard 25df33b9c1 update backoffice submodule 2023-05-08 15:58:00 +02:00
Jacob Overgaard 6bab6e8a0d update backoffice submodule 2023-05-08 09:42:44 +02:00
MoleandGitHub a5744c50ae Merge pull request #14206 from umbraco/v13/bugfix/rename_usergroup_controller
New Backoffice: Rename UserGroup Controllers
2023-05-04 11:22:47 +02:00
Nikolaj 0a64ac5485 Update OpenApi 2023-05-04 10:42:00 +02:00
Nikolaj f71a4fa968 Rename SaveUserGroupRequestModel to CreateUserGroupRequestModel 2023-05-04 10:09:39 +02:00
Nikolaj abdfcf4e14 Rename UserGroupPresentationModel to UserGroupResponseModel 2023-05-04 10:02:07 +02:00
Jacob Overgaard d6aa10cc55 update backoffice submodule 2023-05-02 10:41:41 +02:00
Jacob Overgaard cced44a72f update backoffice submodule 2023-04-28 10:23:22 +02:00
b411452f79 New backoffice: Add new codefile controllers and services (#14157)
* Add scaffolding

* Entities not Entitys

* Remove unececary obsoleted constructor

* Implement create script

* Return a simplified ScriptFile instead of IScript

That file abstraction seems way too bloated, containing a lot of stuff that's not relevant for files, such as IDs and keys.

* Use IScript instead of custom return model

* Add validation when creating script

* Add Get script endpoint

* Add response types

* Add Delete

* Throw if user key not found

* Remove unused maapper

* Add update endpoint

* Add Get by path

* Add create folder endpoint

* Don't pass performingUserId to folder creation

* Remove update folder

* Add delete folder endpoint

* Use specific ScriptFolderOperationStatus instead of ScriptOperationStatus

* Add OperationStatusResult

* Check folder for invalid name

* Check name for invalid characters

* Add partial view snippet endpoint

* Start working on CreatePartialView

* Add create partial view endpoint

* Retrieve key from audit method

* Add operation status results

* Add Get endpoint

* Return 201 when creating

* Add update partial view endpoint

* Add delete endpoint

* Add response types

* Add folder base implementation

* Add folder endpoints

* User property for allowed file extensions

* Rename async method to async

* Break snippet into endpoint in two

* Make content non-nullable

* Remove IService

* Add get by path

* Add viewmodels

* Add create and update models

* Add create stylesheet

* Add update endpoint

* Rename StylesheetControllerBase to StylesheetControllerBase

* Add stylesheet delete

* Rename controller bases

* Add stylesheet folders

* Add status results

* Add response types to folders

* Add richtext rules endpoints

* Add Get all endpoint

* Add get rules by path endpoint

* Aling validates so they're not async

These are private methods, so there's no reason to make them preemptively async

* Add template obsoletions to interface

* Add stream methods

This is evidently used by deploy 🤷

* Obsolete stylesheet operations

* Add get and getall across all services

* Obsolete script operations

* Obsolete old partial view methods

* Add some method docs

* Add compatibility suppression

* Update OpenApi.json

* Rename action

* formatting

* Fix import

* add expression body

* Invert if

* Move base on own line

* Rename file

* Rename to all

* Change to stylesheet instead of script

* Add Umbraco.Code.MapAll to map definitions

* Add comment about auditing

* use publish cancelable async

* use expression body

* formatting

* fix to use pattern matching

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
2023-04-26 13:47:47 +02:00
Jacob Overgaard 17fef47450 backoffice submodule update 2023-04-26 08:07:06 +02:00
Jacob Overgaard 2ce9e338dc update backoffice submodule 2023-04-25 16:23:20 +02:00
Bjarke Berg bde0714b34 Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Document/BlockGridEditorInDocument.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockListEditor/blockListEditorContent.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Languages/languages.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Media/mediaFiles.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Media/mediaSection.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/ModelsBuilder/modelsbuilder.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/partialViews.spec.ts
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Tour/tours.spec.ts
2023-04-25 15:46:10 +02:00
Kenn JacobsenandGitHub d98f635eed Fix DataValueEditor configuration handling + update naming to be more explicit (#14104) 2023-04-25 15:32:29 +02:00
MoleandGitHub d96346313e Return created from invite (#14158) 2023-04-25 14:19:31 +02:00
MoleandGitHub dfa7eff7c2 New backoffice: Fix typo on user model (#14154)
* LastLockoutDate not LastlockoutDate

* Update open api
2023-04-25 10:58:38 +02:00
Kenn JacobsenandGitHub 57377a8f7a Make Block Grid and Block List use System.Text.Json instead of Json.NET (#14125)
* Make block grid and block list use System.Text.Json instead of Json.NET

* Add compat suppressions

* Move block editor models to Core
2023-04-25 10:48:48 +02:00
MoleandGitHub 2e23c81677 New backoffice: Updated missed controller paths (#14130)
* Updated missed controller paths

* Update openapi
2023-04-24 15:22:42 +02:00
f3df3e600f Only add non default version to operation id (#14146)
* Only add version to operationId when the version is not the default version

* Updated OpenApi.json

* A little code formatting

* Update OpenAPI JSON so the tests pass

---------

Co-authored-by: kjac <kja@umbraco.dk>
2023-04-24 14:15:36 +02:00
Jacob Overgaard db70750bba add picker-input importmap 2023-04-20 14:39:24 +02:00
38947e0870 Added functionality to split det swagger doc into multiple definitions (#14126)
* Added functionality to split det swagger doc into multiple definitions. Most (maybe too much) is still shared between the apis.

* Fixed issue with duplicate operation ids when we have multiple versions of an endpoint

* use strong types instead of var

* Updated OpenApi.json

* Formatting

* formatting

* Delete old files that is not implemented in api.common

* Updated openAPi after merge

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
2023-04-20 12:38:31 +02:00
518bb60a45 New backoffice: Use singular name for user and user group controllers (#14121)
* Rename UsersController to UserController

* Rename namespace to User

* Rename UserGroupsControllerBase to UserGroupControllerBase

* Rename namespace to UserGroup

* New backoffice: User and member item endpoints (#14079)

* Implement ByKeys in MemberService

* Implement member item endpoint

* Add routing to static file item controller

* Implement user item endpoint

* Implement user group item endpoint

* return proper response model

* update OpenApi.json

* Add CompatibilitySuppressions

* Cleanup

* Update OpenApi

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Elitsa <elm@umbraco.dk>

* Make user-group item endpoint singular

* Make user item endpoint singular

* Renamer user and user group folders

* Move from Users namespace to user

* Move from UserGroups namespace to UserGroup

* Update OpenApi.json

* Fix namespace after merge

* Move user item endpoint to singular namespace

* Move user group item endpoint to singular namespace

* Fix open api schema

---------

Co-authored-by: Nikolaj Geisle <70372949+zeegaan@users.noreply.github.com>
Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Elitsa <elm@umbraco.dk>
2023-04-20 09:40:48 +02:00
Andreas ZerbstandGitHub b43d3ff98e Updated so it now shows the parentId instead of null (#14123) 2023-04-20 09:11:35 +02:00
7b62fb282f Dedicated cookie setup for new backoffice login (#14122)
* Add a dedicated (temporary) cookie setup for new backoffice logins, so old and new backoffice can co-exist behind separate logins

* use temp management api login endpoint for authentication

* Update OpenAPI JSON

---------

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
2023-04-19 13:32:11 +02:00
Bjarke Berg fff393c9ed Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	src/Umbraco.Cms.Api.Management/ManagementApiComposer.cs
#	src/Umbraco.Core/CompatibilitySuppressions.xml
#	src/Umbraco.Infrastructure/CompatibilitySuppressions.xml
2023-04-19 11:42:01 +02:00
cb682e2f3e New backoffice: User and member item endpoints (#14079)
* Implement ByKeys in MemberService

* Implement member item endpoint

* Add routing to static file item controller

* Implement user item endpoint

* Implement user group item endpoint

* return proper response model

* update OpenApi.json

* Add CompatibilitySuppressions

* Cleanup

* Update OpenApi

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Elitsa <elm@umbraco.dk>
2023-04-19 09:43:01 +02:00
MoleandGitHub cbb8f62457 Fix iso code validator (#14107) 2023-04-17 15:23:34 +02:00
861b883d29 Throw from IUserIdKeyResolver if id/key not found. (#14101)
* Throw from IUserIdKeyResolver if id/key not found. This is too critical to not throw.

* Fixed tests

* Explicitly test that we can resolve super user key/ID from their counterparts

---------

Co-authored-by: kjac <kja@umbraco.dk>
2023-04-14 12:03:25 +02:00
Bjarke Berg d625fee1ad Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	src/Umbraco.Infrastructure/CompatibilitySuppressions.xml
#	src/Umbraco.Infrastructure/Migrations/MigrationPlanExecutor.cs
#	src/Umbraco.Infrastructure/Migrations/UnscopedMigrationBase.cs
#	tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Migrations/MigrationPlanTests.cs
remove double request to get init status
2023-04-14 10:35:30 +02:00
c2af43d9d9 Copy and move API for content and media (#14040)
* Copy and Move API for Content and Media

* Update OpenAPI JSON schema

* Update OpenApi JSON file after merge

* Rename key to id

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-04-14 09:44:52 +02:00
Jacob Overgaard a188844a68 Merge remote-tracking branch 'origin/v13/dev' into v13/dev 2023-04-13 15:52:17 +02:00
Jacob Overgaard d01c95b3d5 simplify return url 2023-04-13 15:52:10 +02:00
Jacob Overgaard b8813aed3d set the path of the login page to /<backofficeurl>/login 2023-04-13 15:51:56 +02:00
Jacob Overgaard 5b94b3051f update temp login page to handle a POST to the authentication url and handle the returnUrl 2023-04-13 15:51:19 +02:00
f26e5d12a0 Management API: Data type or property is used endpoints (#14078)
* Added is-used endpoints

* Updated CompatibilitySuppressions.xml

* Minor cleanup

* Fix issue where only document types was supported. Now also media and member types is supported

* CompatibilitySuppressions.xml

---------

Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-04-13 14:58:16 +02:00
Jacob Overgaard 7be31a5305 update backoffice submodule 2023-04-13 11:23:10 +02:00
Jacob Overgaard a7c082e522 ignore umbraco-package-schema.json 2023-04-12 14:43:46 +02:00
MoleandGitHub f32dcb0823 V13: Ensure Predictable User-Group Keys (#14075)
* Add user group keys to constants

* Update migration to assign the right keys

* Update DataCreator

* Fix FIXME with removing ExcludedUserGroupAliases

* Obsolete group aliases
2023-04-12 11:22:50 +02:00
0f1e7f64ff New backoffice: Tag controller (#14072)
* Implement ByQueryEndpoint

* Implement new async methods on tag service

* dont have nullable query

* Formatting

* Add default implementation to interface

* Allow nullable query in api

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-04-12 09:39:02 +02:00
Jacob Overgaard 507102348d update backoffice submodule 2023-04-12 09:20:42 +02:00
Andreas ZerbstandGitHub bd0fd4237b Removed the acceptance tests from v13 (#14073)
* Removed the acceptance tests from v13

* commented out the pipeline for e2e tests because there are no test left
2023-04-11 15:34:59 +02:00
Bjarke Berg b6c16afeea Fix OpenApi.json 2023-04-05 13:45:51 +02:00
Bjarke Berg b34b1906de Rename key to id 2023-04-05 13:43:54 +02:00
Jacob Overgaard ee1cac68e8 Merge remote-tracking branch 'origin/v13/dev' into v13/dev 2023-04-05 13:18:03 +02:00
Jacob Overgaard 4ead24edc9 add importmap to installer 2023-04-05 13:17:14 +02:00
9fadb3a926 V13: Entity viewports (#14050)
* Add language entity

* Refactor LanguageEntities

* Rename ItemsLanguageController.cs to ItemsLanguageEntityController.cs

* Change route to match old pattern

* Implement datatype item endpoint

* Rename controllers to item instead of entity

* Implement dictionary item endpoint

* Add DocumentItemControllerBase.cs

* Implement ItemDocumentItemController.cs

* Implement documnent-type controller

* Implement media type controller

* Move to item folder

* Implement MemberGroupItem viewport

* Implement member type item viewport

* Implement partial view viewport

* Implement partial view viewport

* Implement Relation type viewport

* Implement script items endpoint

* Refactor FileItemPresentationModelFactory

* Implement StaticFile viewport

* Implement stylesheet viewport

* Implement template item viewport

* Fix up routing

* Implement taking start nodes into account

* Implement filtering by culture too

* Delete old endpoints

* Implement document blueprint endpoint

* Implement media item viewport

* remove unneccesary $

* add fixme comment

* Fix response moedl

* update OpenApi.json

* Update OpenApi.json

* Update openapi file

* filter languages på isocode

* Change to sorted set to avoid duplicates

* Implement GetMultipleAsync for ILanguageService

* Fixed issue with params from GET needs to be querystring

* Removed Icon from base and only return Icon if explicitly set

* Fixed openAPI spec

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-04-05 12:50:41 +02:00
21b0a7ffae New Backoffice: Fix feedback to users controller (#14031)
* Add specific not found results

* Add tests for the enable/disable not found tweak

* Cache ids and key in UserIdKeyResolver

* Don't cache null keys

* BackOffice not Backoffice

* Move fetching the user out of the ChangePasswordUsersController

* Move resolving user out of SetAvatar

* Move resolving user out of Update

* Return more specific notfound in bykey

* Use ErrorResult for all endpoints with unknown errors

* Split integration tests

* Add mappers

* Use ?: consistently

* Add reuseable iso code validator

* Validate ISO code

* Update supressions

* Use method from base to get current user key

* Rename ISo to Iso

* Use keys in services instead of user groups + Added a couple of new validations

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-04-04 15:41:12 +02:00
Bjarke BergandGitHub 6313b8b3a1 Changed "Key" to "Id" in management API (#14045) 2023-04-04 13:20:29 +02:00
Bjarke Berg c8f4ae2e29 Merge remote-tracking branch 'origin/v12/dev' into v13/dev 2023-04-04 09:25:39 +02:00
Jacob Overgaard dbbfc0c69e add https support for development CORS 2023-04-03 14:58:37 +02:00
b981f53254 Fix key names to id and allow sending id on create for datatypes (#14035)
* Changed some keys to ids and fixed so users can provide Ids when creating

* updated OpenApi.json

* Fixed issue with datatypes when wrong propertyEditorAlias was used and allow creating with key

* Updated OpenApi.json

* Handle duplicate names correct

* Fix for parent not found

* Handle if parent is not a container

* Update CompatibilitySuppressions

---------

Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-03-31 13:59:44 +02:00
Bjarke Berg 1f83e9ab19 Merge remote-tracking branch 'origin/v12/dev' into v13/dev 2023-03-29 11:08:53 +02:00
Kenn JacobsenandGitHub fd3bb0fcb8 Add content notifications API (#14010) 2023-03-29 10:48:30 +02:00
9b626d02c8 New backoffice: User controller (#13947)
* Add UserResponseModel

* Add factory to created UserResponseModel

* Add GetByKey controller

* Add GetAllUsers endpoint

* User proper response model

* Make naming consistent

* Order by username in GetAll

* Add user filter endpoint

* Fix includer user states

* Remove gravatar from the backend

* Send user avatars in response

* Add create user model

* start working on create

* Validate the create model

* Add authorization to create

* Use UserRepository instead of UserService to ValidateSessíonId

* Create IBackofficeUserStore interface

This is essentially a core-friendly version of the BackOfficeUserStore, additionally it contains basic methods for managing users, I.E. Get users, save users, create users, etc.

* Remove more usages of user service

* Remove usages of IUserService in BackofficeUserStore

* Add documentation

* Fix tests and DI

* add IBackOfficeUserStoreAccessor to resolve it in singleton services

* Resolve circular dependency

* Remove obsolete constructor

* Add core friendly user manager

* Finish createasync in user service

* Add WIP create endpoint

* Save newly creates users user groups

* Use service scope for user service

* Remove now unnecessary accessors

* Add response types

* Add update user endpoint

* Add EmailUserInviteSender

* Add technology free way of creating confirmation token

* Add invite uri provider

* Add invite user to user service

* Add invite user controller

* Add delete endpoint

* Add operation status responses

* Add operation status responses

* Added temporary file uploads including a repository implementation using local temp folder.

* Add Disable users endpoint

* missing files

* Fixed copy paste error

* Fix create users return type

* Updated OpenApi.json

* Updated OpenApi.json

* Handle if created failed in identity

* Add enable user

* Make users plural in enable/disable

We're doing the operation on multiple entities

* Added file extension check

* Add unlock user endpoint

* Clean up. Removed old TemporaryFileService and UploadFileService and updated dictionary items to use this new items

* Clean up

* Add reset password

* Add UpdateUserGroupsOnUsers method

* Add UpdateUserGroups

* Get rid of stream directly on TemporaryFileModel, and use delegate to open stream instead.

* Fix post merge

* Use keys instead of IDs

* Add ClearAvatar endpoint

* Review changes

* Moved models to their own files

* Reverted launch settings

* Move enlist extension to its own namespace

* Create set avatar endpoint

* Add reponse types

* Remove infrastructure extension after merge

* Add Cmapatibility suppressions

* Add test suppression

* Add integration tests

* Fix issue found in tests

* Add invited user to UserInvitationResult

* Add more tests

* Add update tests

* Hide different tests under parent

* Return DuplicatUserName user operation status if username matches an email

* Add update tests

* Change sorted set to HashSet

It doesn't work if it's not IComparable

* Change ID to Key when checking super

* Add get tests

* Add more GetAllTests

* Move tests to the right namespace

* Add filter test

* Fix including disabled users bug found by test

* Add test to ensure invited user state

* Add test case for UserState.All

* Add more filter tests

* Add enable disable tests

* Add resolver for keys and ids

* Replace usages of IUserService with IUserIdKeyResolver

* Add CompatibilitySuppressions

* Add UserIdKeyResolverTests

* Fix UserIdKeyResolver

* Add missing user operation results

* Updates from review

* ID not key

* Post instead of patch

* Use set instead of params for enable/disable

* Don't call to array

* Use sets for usergroup keys and user keys instead

* LanguageIsoCode instead of Language

* Update CompatibilitySuppressions after changin enumerable to set

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
Co-authored-by: kjac <kja@umbraco.dk>
2023-03-29 08:14:47 +02:00
kjac 313eed96b9 Revert "Add content notifications API"
This reverts commit 8202879ba7.
2023-03-27 07:55:55 +02:00
kjac 8202879ba7 Add content notifications API 2023-03-27 07:55:18 +02:00
af24f304be New Backoffice: Fix total number of items (health checks, log viewer, packages) (#14003)
* Fix total number of items for health check controllers

* Fix total amount of items for log viewer controller

* Fixing AllMigrationStatusPackageController

* Fixing total items for package controllers

* Adding default implementation

* Update Nerdbank.GitVersioning dependency to 3.5.119

---------

Co-authored-by: Ronald Barendse <ronald@barend.se>
2023-03-24 11:47:59 +01:00
Jacob Overgaard 91d4389d2c add router lib to importmap 2023-03-24 11:01:33 +01:00
Jacob OvergaardandGitHub 03f1ff65fe V13: build new backoffice on Azure (#14005)
* add build scripts for new BO so it doesn't run through msbuild

* add node config for max_old_space_size to increase allowed heap size
2023-03-24 10:19:42 +01:00
Jacob Overgaard 5e721da35e bump memory for node.js builds 2023-03-22 16:05:49 +01:00
Jacob Overgaard 7bc5e0e3a1 update backoffice git submodule 2023-03-22 16:00:48 +01:00
Jacob Overgaard 458229a6ee update backoffice git submodule 2023-03-22 15:46:44 +01:00
93da4371e3 V13: Rework attempt pattern to use userkey (#13964)
* Add default super user key to migrations

* Start refactoring all interfaces signatures with ids

* Refactor datatype service to use userKey pattern instead

* Refactor ContentEditingService to use userkeys

* Refactor services to userKey

* Refactor more services to use userkey instead of id

* Refactor RelationService to use userKeys

* Refactor template service to use keys instead of ids

* Refactor fileservice to use keys instead of ids

* Refactor LocalizationService to use keys instead of ids

* Refactor PackagingService to use keys instead of ids

* Refactor TemplateController to use current user keys

* Refactor DataTypeContainerService.cs

* Refactor DataTypeService to use keys instead of ids

* Fix up tests

* Fix up media editing service to use userkey instead of ID

* Update service ctor to avoid ambigious ctors

* refactor DataTypeService

* Refactor DataTypeService to not have a default value for parentKey

* Apply suggestions from code review

Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com>

* Update comment

* Add suppression file

* Add backoffice CompatibilitySuppressions

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com>
2023-03-21 12:41:20 +01:00
Jacob Overgaard 8a8421c841 backoffice git submodule 2023-03-21 12:11:29 +01:00
Jacob Overgaard c26c00474c update importmap to reflect latest backoffice libraries 2023-03-21 12:11:19 +01:00
Bjarke Berg ec9b873fac Added CompatibilitySuppressions files 2023-03-20 09:55:40 +01:00
Bjarke Berg 03afef299d Added CompatibilitySuppressions files 2023-03-20 09:53:22 +01:00
Bjarke Berg 27103355a5 Post merge fixes 2023-03-20 09:37:11 +01:00
Bjarke Berg 8a99222e26 Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	src/Umbraco.Core/CompatibilitySuppressions.xml
#	src/Umbraco.Core/Routing/UmbracoRequestPaths.cs
#	src/Umbraco.Infrastructure/CompatibilitySuppressions.xml
#	src/Umbraco.Web.BackOffice/Controllers/ContentController.cs
#	tests/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/Controllers/ContentControllerTests.cs
2023-03-20 08:49:27 +01:00
835388ced0 Temporary files endpoints for management api (#13944)
* Added temporary file uploads including a repository implementation using local temp folder.

* missing files

* Fixed copy paste error

* Updated OpenApi.json

* Updated OpenApi.json

* Added file extension check

* Clean up. Removed old TemporaryFileService and UploadFileService and updated dictionary items to use this new items

* Clean up

* Get rid of stream directly on TemporaryFileModel, and use delegate to open stream instead.

* Review changes

* Moved models to their own files

* Reverted launch settings

* Update open API JSON file

---------

Co-authored-by: kjac <kja@umbraco.dk>
2023-03-16 08:25:15 +01:00
1e4c17a5f9 V13: Add default superuser key (#13955)
* Add default super user key to migrations

* Minor tweaks

* Obsolete superuser id

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-03-15 10:32:00 +01:00
Kenn JacobsenandGitHub 4fb011e0fc Domains and hosts API (#13963)
* API for domains and hostnames incl. unit tests

* Update Open API json

* Update other unit tests to use new domain service methods where applicable

* Fix merge + update models to new naming scheme

* Handle attempts to add the same domain twice + unit tests for duplicate domain handling

* Review fixes
2023-03-15 10:28:23 +01:00
Jacob Overgaard ea1402de52 update git submodule 2023-03-15 08:06:22 +01:00
Jacob Overgaard 28e41f7cdc update git submodule 2023-03-14 12:52:00 +01:00
Jacob Overgaard 4d24312fe2 update git submodule 2023-03-13 15:32:23 +01:00
Jacob Overgaard 3b49e34e79 Merge remote-tracking branch 'origin/v13/dev' into v13/dev 2023-03-13 15:32:10 +01:00
Jacob Overgaard 6878334c3e add notification as separate library 2023-03-13 15:32:01 +01:00
5ac0087013 Rename data to values (#13892)
* Rename data to values

* Rename data to values

* Update OpenApi.json

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
2023-03-13 15:03:54 +01:00
Kenn JacobsenandGitHub c0975f341c CRUD API for media + get-by-id for media type (#13934)
* CRUD API for media + get by ID for media types

* A little housekeeping for documents (align with media)

* Update Open API json

* Add messages to NotFound results (both content and media)

* Review changes; use same model for content and media URLs + return bad request when trying to move something to trash that is already in trash

* Fix bad merge + rename base (response) classes appropriately between both media and content types
2023-03-13 15:02:30 +01:00
Jacob Overgaard 8df3bca5fe git submodule update 2023-03-13 11:50:06 +01:00
5107375cd8 V13/feature/rename viewmodels to request response (#13952)
* Rename DocumentType/ContentType models

* Rename all viewmodels

* Rename factories

* Update OpenApi.json

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
2023-03-13 10:49:21 +01:00
Jacob Overgaard 44bbf48540 Merge remote-tracking branch 'origin/v13/dev' into v13/dev 2023-03-13 09:57:27 +01:00
Jacob Overgaard 22937cb550 optimise importmaps 2023-03-08 14:23:46 +01:00
Andreas ZerbstandGitHub 4d6e1e9531 Removed test file because the test are broken (#13924)
* Removed test file because the test are broken

* Removed outdated failing tests
2023-03-08 14:04:59 +01:00
Bjarke Berg 381c0e0978 Fixed issue with serializing structured values from serilog. 2023-03-08 13:30:58 +01:00
Bjarke Berg de6df01485 Merge remote-tracking branch 'origin/v12/dev' into v13/dev 2023-03-08 11:12:21 +01:00
1b8ce54e49 Remove Json.NET dependencies for more property editors (#13912)
* Make the Tags property editor JSON serialization agnostic

* Make the Multiple Value editor JSON serializer agnostic

* Make Media Picker 3 value converter work with System.Text.Json instead of Json.NET

* Make Image Cropper value converter work with System.Text.Json instead of Json.NET

* Remove Json.NET dependencies from ImageCropperTemplateExtensions

* Update src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyValueEditor.cs

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* Update src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyValueEditor.cs

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* Update src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* Update src/Umbraco.Infrastructure/PropertyEditors/TagsPropertyEditor.cs

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* Update src/Umbraco.Infrastructure/PropertyEditors/TagsPropertyEditor.cs

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* Update src/Umbraco.Infrastructure/PropertyEditors/TagsPropertyEditor.cs

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

---------

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2023-03-07 14:31:27 +01:00
Jacob Overgaard 3b77debbfb update git submodule 2023-03-03 11:29:05 +01:00
Jacob Overgaard 25ac2253b5 Merge remote-tracking branch 'origin/v13/dev' into v13/dev 2023-03-02 14:51:09 +01:00
Jacob Overgaard 7316a0e82c add importmap to Default.cshtml 2023-03-02 14:50:51 +01:00
Nikolaj GeisleandGitHub f3ca18ccbf Apply skip take after (#13903) 2023-03-02 14:09:22 +01:00
Jacob Overgaard cbfa841413 add gitignore stuff from old executable 2023-03-02 13:52:35 +01:00
Bjarke Berg d53ecc16dd Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Media/mediaSection.spec.ts
2023-03-02 08:50:05 +01:00
27ca36db53 V13: relation type controller (#13856)
* Create RelationTypeControllerBase.cs

* Implement ByKey endpoint

* Move controllers

* Implement ByRelationTypeKeyRelationController

* Refactor relation service to use skip/take in interface

* change httpget

* Implement object types endpoint

* Add ObjectTypeViewModelFactory.cs

* Change signature to IActionResult

* Implement CreateRelationTypeController.cs

* Implement CreateRelationTypeController.cs

* Add optional key parameter to RelationType

* Add optional key to RelationTypeSavingViewModel

* Update ProducsResponseType

* Implement UpdateRelationTypeController

* Update routes

* Implement DeleteRelationTypeController

* Remove key from UpdatingViewmoDel

* Implement UpdatingViewModel factory method

* Update relationType factory

* Fix paging for object types

* Implement CreateAsync

* Update create action to use CreateAsync

* Implement update async

* Add default implementations to avoid breaking changes

* actually use userIds

* Add ProducesResponseType status 400 to endpoints

* Implement new DeleteAsync method

* Update OpenApi.json

* Add mapping to DI

* Update 404 to return proper HTTP status

* Add not found to ByKey action

* Rename viewmodels to request/response

* Update OpenApi.json

* All RelationServiceTests.cs

* Add allowed object types test

* Fix grouping

* Implement AllowedRelationObjectTypesService.cs

* Refactor view model factory to use new service

* Implement non-happy path tests

* Implement allowed child/parent object types

* refactor test to return proper relationTypeOperationStatus

* Add can create relation type with key

* Add Id test

* formatting

* Refactor service to have validation logic in save method

* move object types endpoint to own silo

* Delete unused using

* Update OpenApi.json

* Update OpenApi.json

* Update tests to user proper child/parent

* Implement RelationTypeBaseModel

* Update OpenApi.json

* Use array instead of enumerable

* Rename view model factory to presentation factory

* Rename GetPagedByRelationTypeKey

* Rename IRelationViewModelFactory

* Rename IRelationTypeViewModelFactory

* Update error description

* Update OpenApi.json

* Update OpenApi.json

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-03-01 08:51:17 +01:00
Bjarke BergandGitHub a00421602e Merge pull request #13891 from umbraco/v13/feature/content-create-update-delete
Create/update/delete API for Document
2023-02-28 16:00:48 +01:00
Bjarke BergandGitHub 1d8941cf28 Merge pull request #13884 from umbraco/v13/feature/extension-model
Add extension model for new backoffice
2023-02-28 10:26:26 +01:00
b9ffd01f69 Update src/Umbraco.Core/Configuration/Models/PackageManifestSettings.cs
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-02-28 09:43:00 +01:00
kjac 0f95dbbfa6 Review changes and fixes 2023-02-28 08:36:48 +01:00
459e6f5421 Update src/Umbraco.Infrastructure/Manifest/PackageManifestReader.cs
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-02-28 08:01:17 +01:00
b5de843b84 Update src/Umbraco.Infrastructure/Manifest/PackageManifestService.cs
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-02-28 07:55:10 +01:00
Bjarke Berg 8bce0074c0 Merge branch 'v13/dev' into v13/feature/content-create-update-delete 2023-02-28 07:51:24 +01:00
Jacob Overgaard 7535576edf update git submodule 2023-02-27 14:43:16 +01:00
Jacob Overgaard 95a56238c9 update git submodule 2023-02-27 14:42:49 +01:00
kjac 51bb7b01bd Update open API JSON with renamed model names 2023-02-27 11:28:26 +01:00
kjac 207c1b6dde Rename ViewModel to ResponseModel + rename ViewModel factory to Presentation factory 2023-02-27 11:27:26 +01:00
kjac 9152d05613 Update open API JSON 2023-02-27 11:19:17 +01:00
kjac 34fa4aa5fc Clean up models 2023-02-27 09:25:35 +01:00
kjac 7d15e6d5ea Merge branch 'v13/dev' into v13/feature/content-create-update-delete 2023-02-27 08:42:13 +01:00
5e90fa26c1 V13: Add parentkey to notifications (#13832)
* Add parent key to CopyingNotification

* Use parentkey on notifications

* Implement ParentKeys for Copying notification

* Obsolete parentId

* Implement MoveToEventInfoBase

* Refactor MovingToRecycleBinNotification to use the new MoveEVentInfoBase

* Refactor MediaMovingToRecycleBinNotification

* Refactor MovedToRecycleBinNotification to use new MoveEventInfo

* Refactor ContentMovedToRecycleBinNotification to use new MoveEventInfo

* Start implementing parent key in moveinfo

* Add FIXME's to move methods

* Refactor Move to get parentKey for descendants

* Add FIXME for move method

* Use MoveToRecycleBinEventInfo in RelateOnTrashNotificationHandler

* Add fixme's to DataTypeRepository

* Add obsolete messages

* Revert changes in ContentTypeServiceBaseOfTRepositoryTItemTService.cs

* Fix bad indentation

* Pass the recursive variable

* Revert changes in ContentService.cs

* Refactor MoveEventInfo to not duplicate equals method

* Refactor Equals to not duplicate code

* Add UnitTests of Equals

* make equals public and add non-happy path tests

* Remvoe duplicate call to base

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
2023-02-27 08:40:17 +01:00
kjac 502713fdbb Rename models as per new naming conventions + clean up duplicate models 2023-02-23 16:57:49 +01:00
kjac 9e8a0645cd Merge branch 'v13/dev' into v13/feature/content-create-update-delete 2023-02-23 16:50:19 +01:00
kjac 997f568303 Make the package manifest endpoint non-paginated 2023-02-23 16:49:20 +01:00
kjac 583b10562d Add missing compat suppression 2023-02-23 15:37:47 +01:00
kjac a70d76e4b5 Renamed controller for consistency 2023-02-23 15:37:15 +01:00
kjac e3b216c087 Re-apply missing legacy manifest renaming + re-generate compat suppressions after merge 2023-02-23 15:36:59 +01:00
kjac 5d2a90f974 Merge branch 'v13/dev' into v13/feature/extension-model
# Conflicts:
#	src/Umbraco.Cms.Api.Management/Controllers/Package/PackageControllerBase.cs
#	src/Umbraco.Cms.Api.Management/DependencyInjection/PackageBuilderExtensions.cs
#	src/Umbraco.Cms.Api.Management/ManagementApiComposer.cs
#	src/Umbraco.Core/CompatibilitySuppressions.xml
#	src/Umbraco.Infrastructure/CompatibilitySuppressions.xml
#	src/Umbraco.Infrastructure/Serialization/ContextualJsonSerializer.cs
#	src/Umbraco.Web.BackOffice/CompatibilitySuppressions.xml
2023-02-23 15:28:44 +01:00
c2ecc8dc33 New Backoffice: Package controller (#13578)
* Adding migration to update the default GUID value of created packages

* Updating the GUID if it is the default value when a package is saved

* Adding PackageDefinitionViewModel for representing a package

* Adding a mapping for package representation

* Adding PackageControllerBase, GetAllCreated and GetEmpty endpoints

* Adding GetCreatedByKey endpoint

* Adding GetByKey implementation for created packages

* Include MapAll comment

* Adding Download package endpoint

* Saving created package endpoint

* Adding a factory to create a PackageDefinition from view model

* Cleanup

* Fix error message

* Check for duplicate package name

* Remove commented out DuplicateNameException

* Moving created packages to /created folder/base

* Implement delete endpoint

* Update OpenApi.json

* Fix package route

* Fix OpenApi.json

* Add Ok() around the result

* Create PackageBuilderExtensions

* Adding suppression changes

* Cleanup

* Use ProblemDetailsBuilder

* Extract collecting installed packages from package migration plans into its own method

* Use GetInstalledPackagesFromMigrationPlans to return all migration statuses

* Add Status to DictionaryControllerBase ProblemDetails

* Implement RunMigrationPackageController

* Adding more information to the log message

* Update OpenApi.json

* Change param name

* Fix OpenApi.json

* Fix response type for Log viewer endpoint

* Remove EmptyPackageController

* Rename to RunPendingPackageMigrations

* Introduce new PackageOperationStatus

* Making methods async and introducing new Create, Update and Delete methods

* Fix async calls

* Fix Mapper - multiple enumeration and cleanup

* Creating special action models

* Fixing the factory with new models changes

* Service implementation changes

* Removing SaveCreatedPackageController as the functionality is split between Create and UpdateCreatedPackageController

* Utilize the new DeleteCreatedPackageAsync

* Refactor DownloadCreatedPackageController as some responsibility is moved to the service

* Refactor PackagingService to use auditService

* Refactor PackagingService to use skip/take

* Refactor services to return pagedmodel

* Refactor controller to use new return value

* update OpenApi.json

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
2023-02-23 14:36:21 +01:00
b96302a9da V13: Audit log controller (#13842)
* Implement AuditLogByTypeViewModel

* Add GetLogs endpoint

* Implement AuditLogViewModelFactory and use it

* Remove mapping and do that in ViewModelFactory

* Add Skip take pagination to AuditService.cs

* Get entity key from repository

* Only create filter if sincedate has value

* Refactor to handle enitity not being found

* Add by type route

* Rename AuditLogViewModel.cs

* Add CreateAuditLogWithUsernameViewModel method to factory

* Rename method in factory

* Fix up controllers to use async service

* Refactor to use pagedModel

* Update sincedate query

* Add FIXME

* Move entity call in scope

* Rename methods to async

* Update src/Umbraco.Core/PaginationHelper.cs

* Refactor to use IActionResult

* Audit log in two words

* Fix up by key

* Fix routing

* Fix ByType

* Update ByType routing

* Refactor to also pass DateStamp

* Add Key to WithUserNameViewModel

* Refactor extension method to call new GetAsync method

* use new GetAsync method

* Rename models and implement base class

* Update OpenApi.json

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-02-23 11:32:24 +01:00
kjac 93149160a7 Make various value editors handle their respective data as concrete types rather than strings or otherwise strange legacy data formats 2023-02-23 09:12:10 +01:00
kjac 710ae3c788 Make the JSON object converter return generic lists of types whenever applicable - and JsonArray for JSON objects. 2023-02-23 09:09:08 +01:00
kjac 767e3cd9eb Add tests for content editing service 2023-02-23 07:31:05 +01:00
Bjarke Berg 37ac85ee96 Merge remote-tracking branch 'origin/v12/dev' into v13/dev 2023-02-23 07:18:25 +01:00
46cc9d6a97 V13: Add Guids to Users (#13868)
* Add MSSQL migration

* Make upgrade possible when user doesn't have a key yet

* Migrate SQLite

* Migrate the external login column

* Fix logging in after migration

* Handle fake GUID correctly

* Make GetByKey async

* Resolve external logins by key instead of id

* Remove usage of naive UserIdToInt

* Dont use ToGuid for property type defaults

* Use constant GUID for user groups

* Ensure that the same GUID is used to create the root user.

* Add migration for two factor logins

* Add default implementations

* Fix unit test

* Remove TODO

* Fix integration tests

* Add default implementation instead of throwing

Co-authored-by: Bjarke Berg <mail@bergmania.dk>

* Make SQLServer migration idempotent

* Add comment about SQLite

* Fix typo

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-02-22 12:33:41 +01:00
kjac 95ec06e119 Fix model name clash in Swagger 2023-02-22 11:39:14 +01:00
kjac 6a0f6267f1 Add missing JSON converters to configuration editor serializer 2023-02-22 11:28:21 +01:00
Bjarke BergandGitHub f734f1fc6a Merge pull request #13861 from umbraco/v13/bugfix/fixed_profiling_endpoints
Fixed profiling status endpoints and added an update endpoint
2023-02-22 07:27:52 +01:00
Nikolaj 74f7ab4e1a Check if value is false consistently 2023-02-21 15:37:49 +01:00
Nikolaj 3608540d45 Use is false instead of negation 2023-02-21 15:35:36 +01:00
0619a7de41 Use keys for tracked references (#13849)
* Use Keys for tracked references instead of int id's.

* Updated OpenApi.json

* Handle filterMustBeIsDependency consistently

---------

Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
2023-02-21 15:20:34 +01:00
kjac cf12b9540e Merge branch 'v13/dev' into v13/feature/content-create-update-delete
# Conflicts:
#	src/Umbraco.Cms.Api.Management/Controllers/Document/ByKeyDocumentController.cs
#	src/Umbraco.Cms.Api.Management/Controllers/Document/DocumentControllerBase.cs
#	src/Umbraco.Cms.Api.Management/DependencyInjection/DocumentBuilderExtensions.cs
#	src/Umbraco.Cms.Api.Management/Mapping/Content/ContentMapDefinition.cs
#	src/Umbraco.Cms.Api.Management/Mapping/Document/DocumentMapDefinition.cs
#	src/Umbraco.Cms.Api.Management/ViewModels/Content/ContentViewModelBase.cs
#	src/Umbraco.Cms.Api.Management/ViewModels/Content/VariantViewModelBase.cs
#	src/Umbraco.Cms.Api.Management/ViewModels/Document/DocumentViewModel.cs
#	src/Umbraco.Infrastructure/Serialization/SystemTextJsonSerializer.cs
2023-02-21 14:07:36 +01:00
2eebd0558c Document and document type read API (#13853)
* Basic structure for document and document type read API

* Handle unpublished, non-variant content

* Expose content type key on ContentTypeSort

* Add the remaining properties to document type (minus list view info, still pending)

* Obsolete more ILocalizationService usage

* Add URLs and template data to document view model

* Clean up + add proprety type appearance

* update submodule commit

* front-end commit

* latest front-end commit

* latest commit

* latest front-end commit

* Rename content property to content value in view model layer

* Add contextual JSON serialization as default JSON serializer

* Add FIXME to content type sort + rearrange constructor parameters

* Fix broken remark tag

* Whitelist breakage for ContentTypeSort

* Add variance info to property type output

* Update src/Umbraco.Cms.Api.Management/Controllers/Document/ByKeyDocumentController.cs

Co-authored-by: Bjarke Berg <mail@bergmania.dk>

* Update src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ByKeyDocumentTypeController.cs

Co-authored-by: Bjarke Berg <mail@bergmania.dk>

* Update src/Umbraco.Cms.Api.Management/Factories/ContentUrlFactory.cs

Co-authored-by: Bjarke Berg <mail@bergmania.dk>

* Add a few FIXME comments about async entity retrieval

---------

Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-02-21 13:40:41 +01:00
Bjarke Berg 14d9fe796a Fix test 2023-02-21 12:19:56 +01:00
Bjarke Berg ed25342311 Fixed tess 2023-02-21 11:28:21 +01:00
kjac d7ad194a5b Merge branch 'v13/dev' into v13/feature/content-create-update-delete 2023-02-21 09:47:44 +01:00
kjac ff90e2a865 Add async get method to content editing service 2023-02-21 09:46:23 +01:00
kjac 9b63d33b33 Merge branch 'v13/feature/content-and-content-type-read-api' into v13/feature/content-create-update-delete 2023-02-21 09:33:21 +01:00
kjac 8541919880 Add a few FIXME comments about async entity retrieval 2023-02-21 09:32:49 +01:00
6982b38ebd Update src/Umbraco.Cms.Api.Management/Factories/ContentUrlFactory.cs
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-02-21 09:22:19 +01:00
ee4bfa8f5a Update src/Umbraco.Cms.Api.Management/Controllers/DocumentType/ByKeyDocumentTypeController.cs
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-02-21 09:22:09 +01:00
c269ebc347 Update src/Umbraco.Cms.Api.Management/Controllers/Document/ByKeyDocumentController.cs
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-02-21 09:22:00 +01:00
kjac a541e24508 Add variance info to property type output 2023-02-21 09:18:57 +01:00
Bjarke Berg be8f120851 Updated OpenApi.json 2023-02-20 15:08:29 +01:00
Bjarke Berg 0d29ad9333 Moved logic from all around into the repository 2023-02-20 14:42:12 +01:00
Bjarke Berg 0ce5a5bb29 Fixed nonodes page css 2023-02-20 14:25:58 +01:00
Bjarke Berg 3587172e02 Fixed and added profiling endpoints 2023-02-20 14:22:35 +01:00
kjac 51189febfb Make Multi URL Picker value editor able to utilize System.Text.Json 2023-02-20 11:09:57 +01:00
kjac 361db0ed3c Add create, update and delete (move to recycle bin) operations for Document 2023-02-20 11:08:22 +01:00
kjac e12fbdf5b7 Add Udi and GuidUdi support in JSON serializer 2023-02-20 11:05:56 +01:00
kjac ec46cbcd71 Make JSON object converter return JsonArray for arrays of JSON items 2023-02-20 11:04:57 +01:00
kjac df7cb851e8 Whitelist breakage for ContentTypeSort 2023-02-18 14:15:19 +01:00
kjac 6f726c3e67 Fix broken remark tag 2023-02-18 14:14:46 +01:00
kjac 0bc08e6a91 Add FIXME to content type sort + rearrange constructor parameters 2023-02-18 13:58:02 +01:00
kjac 323a1b731b Add contextual JSON serialization as default JSON serializer 2023-02-18 13:41:54 +01:00
Andreas ZerbstandGitHub 1f7874dfc8 Removed failing test (#13846) 2023-02-17 11:46:38 +01:00
Bjarke BergandGitHub 8d1218374f Merge pull request #13843 from umbraco/v13/feature/website_assets_directly_from_static_assets
V13: website assets directly from static assets
2023-02-17 10:02:39 +01:00
Bjarke Berg 889f87f2ae Added missing files and updated gitignore 2023-02-17 08:32:07 +01:00
Bjarke Berg 85436ee7c9 check out submodules too 2023-02-16 15:30:52 +01:00
Bjarke Berg 8f9c67ffee Handle static assets for the website directly in static assets project. These should not be build by the backoffice scripts as they are not owned by backoffice 2023-02-16 15:15:59 +01:00
Bjarke BergandGitHub d7ef924c32 Miniprofiler for v13 (#13841)
* Updated miniprofiler and added a few configurations

* added fixme

* Remove file that should not have been committed

* added ignore list. We check the entire path and ignore client requests anyway
2023-02-16 13:08:57 +01:00
Bjarke Berg a8b6eb714d Merge remote-tracking branch 'origin/v12/dev' into v13/dev 2023-02-16 11:16:30 +01:00
5182f46bdb New Backoffice: User Groups Controller (#13811)
* Add key to UserGroupDto

* Fix renaming table in sqlite

The SqliteSyntaxProvider needed an overload to use the correct query

* Start work on user group GUID migration

* Add key index to UserGroupDto

* Copy over data when migrating sqlite

* Make sqlite column migration work

* Remove PostMigrations

These should be replaced with Notification usage

* Remove outer scope from Upgrader

* Remove unececary null check

* Add marker base class for migrations

* Enable scopeless migrations

* Remove unnecessary state check

The final state of the migration is no longer necessarily the final state of the plan.

* Extend ExecutedMigrationPlan

* Ensure that MigrationPlanExecutor.Execute always returns a result.

* Always save final state, regardless of errors

* Remove obsolete Execute

* Add Umbraco specific migration notification

* Publish notification after umbraco migration

* Throw the exception that failed a migration after publishing notification

* Handle notification publishing in DatabaseBuilder

* Fix tests

* Remember to complete scope

* Clean up MigrationPlanExecutor

* Run each package migration in a separate scope

* Add PartialMigrationsTests

* Add unhappy path test

* Fix bug shown by test

* Move PartialMigrationsTests into the correct folder

* Comment out refresh cache in data type migration

Need to add this back again as a notification handler or something.

* Start working on a notification test

* Allow migrations to request a cache rebuild

* Set RebuildCache from MigrateDataTypeConfigurations

* Clean MigrationPlanExecutor

* Add comment explaining the need to partial migration success

* Fix tests

* Allow overriding DefinePlan of UmbracoPlan

This is needed to test the DatabaseBuilder

* Fix notification test

* Don't throw exception to be immediately re-caught

* Assert that scopes notification are always published

* Ensure that scopes are created when requested

* Make test classes internal.

It doesn't really matter, but this way it doesn't show up in intellisense

* Add notification handler for clearing cookies

* Add CompatibilitySuppressions

* Use unscoped migration for adding GUID to user group

* Make sqlite migration work

It's really not pretty, square peg, round hole.

* Don't re-enable foreign keys

This will happen automatically next time a connection is started.

* Scope database when using SQLServer

* Don't call complete transaction

* Tidy up a couple of comment

* Only allow scoping the database from UnscopedMigrationBase

* Fix comment

* Remove remark in UnscopedMigrationBase as it's no longer true

* Add keys when creating default user groups

* Map database value from DTO to entity

* Fix migration

Rename also renamed the foreign keys, making it not work

* Make migration idempotent

* Fix unit test

* Update CompatibilitySuppressions.xml

* Add GetUserGroupByKey to UserService

* Add ByKey endpoint

* Add UniqueId to AppendGroupBy

Otherwise MSSQL grenades

* Ensure that languages are returned by PerformGetByQuery

* add POC displaying model

* Clean up by key controller

* Add GetAllEndpoint

* Add delete endpoint

* Use GetKey to get GUID from id

Instead of pulling up the entire entity.

* Add UserGroup2Permission table

* Fetch the new permissions when getting user groups

* Dont ToString int to parse it to a short

I'm pretty sure this is some way old migration type code that doesn't make any sense anymore

* Add new relation to GetDeleteClauses

* Persist the permissions

* Split UserGroupViewModel into multiple models

This is to make it possible to make endpoints more rest-ish

* Bootstrap create and update endpoints

* Make GetAllUserGroupController paged

* Add method to create IUserGroup from UserGroupSaveModel

* Add sanity check version of endpoint

* Fix persisting permissions

* Map section aliases to the name the frontend expects

This is a temporary fix till we find out how we really want to handle this

* Fix up post merge

* Make naming more consistent

* Implement initial update endpoint

* Fix media start node

* Clean name for XSS when mapping to IUserGroup

* Use a set instead of a list for permission names

We don't want dupes

* Make permission column nvarchar max

* Add UserGroupOperationStatuses

* Add IUserGroupAuthorizationService

* Add specific user group creation method to user service

* Move validating and authorizing into its own methods

* Add operation result to action result mapping

* Update create controller to use the create method

* Fix create end point

* Comment out getting current user untill we have auth

* Add usergroup service

* Obsolete usergroup things from IUserService

* Add update to UserGroupService interface

* User IUserGroupService in controllers

* User async notifications overloads

* Move authorize user group creation into its own service

* Add AuthorizeUserGroupUpdate method

* Make new service implementations internal and sealed

* Add update user

* Add GetAll to usergroup service

* Remove or obsolete usages of GetAllUserGroups

* Add usergroup service to DI

* Remove usage of GetGroupsByAlias

* Remove usages of GetUserGroupByAlias

* Remove usage of GetUserGroupById

* Add new table when creating a new database

* Implement Delete

* Add skip and take to getall

* Move skip take into the service

* Fixup suggestions in user group service

* Fixup unit tests

* Allow admins to change user groups they're not a part of

* Add CompatibilitySuppressions

* Update openapi

* Uppdate OpenApi.json

again

* Add missing compatibility suppression

* Added missing type info in ProducesResponseTypeAttribute

* Added INamedEntityViewModel and added on the relevant view models

* Fixed bug, resulting in serialization not being the same as swagger reported. Now all types objects implementing an interface, is serialized with the $type property

* updated OpenApi.json

* Added missing title in notfound response

* Typo

* .Result to .GetAwaiter().GetResult()

* Update comment to mention it should be implemented on CurrentUserController

* Validate that start nodes actually exists

* Handle not found consistently

* Use iso codes instead of ids

* Update OpenAPI

* Automatically infer statuscode in problemdetails

* Ensure that the language exists

* Fix usergroup 2 permission index

* Validate that group name and alias is not too long

* Only return status from validation

We're just returning the same usergroups, and this is less boilerplate code

* Handle empty and null group names

* Remove group prefix from statuses

* Add some basic validation tests

* Don't allow updating a usergroup to having a duplicate alias

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-02-16 09:39:17 +01:00
kjac 41fbaa2343 Merge branch 'v13/dev' into v13/feature/content-and-content-type-read-api 2023-02-16 09:27:35 +01:00
kjac e0c396afd6 Rename PluginConfiguration to PackageManifest + a little more legacy manifest renaming 2023-02-15 15:17:50 +01:00
kjac d2ed03a5d8 Rename old manifest stuff to legacy manifest 2023-02-15 14:58:10 +01:00
Bjarke Berg 808d563aa0 Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	src/Umbraco.Core/Models/PublishedContent/PublishedValueFallback.cs
2023-02-15 14:19:19 +01:00
kjac 04ea016293 Merge branch 'v13/dev' into v13/feature/extension-model 2023-02-15 14:06:15 +01:00
Bjarke BergandGitHub bf4e745b6a Updated OpenIddict to v4 (#13830)
* Updated OpenIddict to v4 and when through the migration guide.

(SetAuthorizationEndpointUris and SetTokenEndpointUris should not start with a leading / anymore)

* Fixed issue where the old backoffice did not build

* Fixed build

* Fake a change - hopefully npm can see the file now?

* try using npm install instead of npm ci

* Another trial

* remove build of old backoffice

* Oops build new backoffice - not the old

* rollback changes to static assets

* Foreach csproj file instead. Fix for breaking change in dotnet sdk 7.0.200
2023-02-15 13:56:45 +01:00
kjac e4223ef2de Use async telemetry report in ReportSiteTask 2023-02-14 19:08:21 +01:00
kjac 4087f7805e Rename ExtensionManifest to PluginConfiguration 2023-02-14 16:59:08 +01:00
Jacob Overgaard a04ae368c8 update git submodule 2023-02-14 15:43:35 +01:00
kjac 92e53c236e Rename extension file to umbraco-package.json 2023-02-14 14:22:23 +01:00
kjac ba87025de8 Cache manifests in service layer 2023-02-14 11:39:56 +01:00
kjac bdffbb49ae Add async caching extension methods 2023-02-14 11:39:39 +01:00
kjac 341db24ec0 Rename manifest reader method 2023-02-14 10:52:30 +01:00
kjac 51f2b6cd88 Rename content property to content value in view model layer 2023-02-14 10:47:16 +01:00
kjac 1868269905 Merge branch 'v13/dev' into v13/feature/content-and-content-type-read-api
# Conflicts:
#	src/Umbraco.Web.UI.New.Client
2023-02-14 10:33:51 +01:00
kjac bd61ac14e4 Add unit tests 2023-02-14 10:19:23 +01:00
Bjarke BergandGitHub 3e8247f324 add response location header for 201 (#13829)
* Fixed issues where we returned incorrectly 201 with CreatedResultViewModel

* Updated OpenAPI Spec

* Fixed OpenApi

* Added response header to swagger when 201 result

* Clean up
2023-02-14 09:48:09 +01:00
kjac b34f0280c5 Move System.Text.Json serializer to Infrastructure project 2023-02-14 07:03:25 +01:00
kjac eb0ec7bee8 Initial implementation for extension manifests 2023-02-13 19:03:58 +01:00
Kenn JacobsenandGitHub 620a673fa3 A little Monday cleanup (#13823)
* Introduce root key constant

* Do not enforce ProblemDetails on every non-success response from the API + remove invalid NotFoundResult response types from various endpoints

* Update OpenAPI JSON contract to reflect the new NotFound results
2023-02-13 15:16:21 +01:00
Jacob Overgaard 233be8dc8f update git submodule 2023-02-13 10:07:25 +01:00
Jacob Overgaard 66118e556a update git submodule 2023-02-13 09:06:15 +01:00
Niels Lyngsø 89a3243771 latest front-end commit 2023-02-10 16:29:16 +01:00
Niels Lyngsø fb47b02ed0 latest commit 2023-02-10 16:27:35 +01:00
Niels Lyngsø 84c6d3b204 latest front-end commit 2023-02-10 16:23:35 +01:00
Niels Lyngsø b70491a782 front-end commit 2023-02-10 15:28:39 +01:00
Niels Lyngsø 5722108454 Merge remote-tracking branch 'origin/v13/dev' into v13/feature/content-and-content-type-read-api 2023-02-10 15:17:02 +01:00
Niels Lyngsø 72c5ec696d update submodule commit 2023-02-10 15:16:41 +01:00
50f19549b6 Add move/copy operations to datatype API (#13791)
* Add move/copy operations to datatype API

* Add compat suppressions for new interface methods

* Regenerate OpenAPI JSON

* Update OpenApi.json

* Ensure we can copy a datatype to root + make the target key nullable (explicit) for move and copy operation models

* Handle parent not found status

* Update the OpenAPI spec to reflect new nullability

* Cleanup

---------

Co-authored-by: Elitsa Marinovska <elm@umbraco.dk>
2023-02-10 15:11:49 +01:00
Jacob Overgaard 525d73d205 update git submodule 2023-02-10 11:25:37 +01:00
Kenn JacobsenandGitHub 36dc35f8aa Add "move" to dictionary API (#13810)
* Sanitize dictionary overview and export actions

* Amend dictionary services with async and attempt pattern + isolate temporary file handling in its own service.

* Update OpenAPI schema to match new dictionary bulk actions

* Implement move API for dictionary items.

* Add unit tests for dictionary item move

* Fix merge

* Update OpenAPI json after merge
2023-02-10 08:32:24 +01:00
Jacob Overgaard 42f8cde259 update to backoffice directory 2023-02-09 13:32:20 +01:00
9b7bf81ad1 Serialization and deserialziation with polymorphism (#13762)
* Support polymophism when sending or receiving interfaces

* Handle attempts to deserialize interfaces nicer

* updated OpenApi.json

* Update src/Umbraco.Cms.Api.Common/Json/NamedSystemTextJsonInputFormatter.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Cms.Api.Management/ManagementApiComposer.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Cms.Api.Management/OpenApi/ConfigureUmbracoSwaggerGenOptions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Infrastructure/Serialization/UmbracoJsonTypeInfoResolver.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Infrastructure/Serialization/UmbracoJsonTypeInfoResolver.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Infrastructure/Serialization/UmbracoJsonTypeInfoResolver.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Infrastructure/Serialization/UmbracoJsonTypeInfoResolver.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Infrastructure/Serialization/UmbracoJsonTypeInfoResolver.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Infrastructure/Serialization/UmbracoJsonTypeInfoResolver.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Infrastructure/Serialization/UmbracoJsonTypeInfoResolver.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Infrastructure/Serialization/UmbracoJsonTypeInfoResolver.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Invert to avoid nesting

* Updated OpenApi.json

* Update schema

---------

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>
2023-02-08 18:29:30 +01:00
Elitsa MarinovskaandGitHub 20534b7a97 New Backoffice: Health check controller refactor (#13763)
* Refactor AllHealthCheckGroupController to return just the names of the groups + changes in the HealthCheckFactory

* Introduce a new "get by name without results" endpoint

* Create a "check" endpoint

* View models changes

* Factory renaming changes

* Remove Task.FromResult

* Update OpenApi.json

* Minor updates

* Inject HealthCheckCollection directly into the factory
2023-02-08 14:16:21 +01:00
fdf416550a Refactor dictionary bulk action APIs (#13786)
* Sanitize dictionary overview and export actions

* Amend dictionary services with async and attempt pattern + isolate temporary file handling in its own service.

* Update OpenAPI schema to match new dictionary bulk actions

* Update src/Umbraco.Cms.Api.Management/Services/DictionaryItemImportService.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Cms.Api.Management/Services/DictionaryItemImportService.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Cms.Api.Management/Services/TemporaryFileService.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Cms.Api.Management/ViewModels/Dictionary/DictionaryImportModel.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Refactor - split dictionary import handling into smaller methods

* Rename view model due to name clash in new SwaggerGen + update OpenAPI JSON file

---------

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>
2023-02-08 13:18:08 +01:00
Bjarke Berg b582bfa39b Merge remote-tracking branch 'origin/v13/dev' into v13/dev 2023-02-08 12:55:31 +01:00
Bjarke Berg e5609592cd Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	src/Umbraco.Core/Models/ContentEditing/Language.cs
#	src/Umbraco.Core/Models/DictionaryItem.cs
#	src/Umbraco.Core/Models/DictionaryItemExtensions.cs
#	src/Umbraco.Core/Models/DictionaryTranslation.cs
#	src/Umbraco.Core/Models/IDictionaryTranslation.cs
#	src/Umbraco.Core/Models/Language.cs
#	src/Umbraco.Core/Models/Membership/ReadOnlyUserGroup.cs
#	src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs
#	src/Umbraco.Core/Services/DataTypeService.cs
#	tests/Umbraco.Tests.Common/Builders/LanguageBuilder.cs
#	tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Editors/UserEditorAuthorizationHelperTests.cs
2023-02-08 12:38:43 +01:00
Kenn JacobsenandGitHub 59448aeaac Add "Model" postfix for all models in the Swagger output (#13806) 2023-02-08 12:34:11 +01:00
Nathan Woulfe b5e87a82f2 Merge branch 'v13/dev' of https://github.com/umbraco/umbraco-cms into v13/dev 2023-02-08 09:47:02 +10:00
Nathan Woulfe 41a03f4b8b uses correct constant for dictionary icon (needs to be added to uui icon registry) 2023-02-08 09:46:58 +10:00
6808a63e73 New backoffice: Add GUIDS to user groups (#13672)
* Add key to UserGroupDto

* Fix renaming table in sqlite

The SqliteSyntaxProvider needed an overload to use the correct query

* Start work on user group GUID migration

* Add key index to UserGroupDto

* Copy over data when migrating sqlite

* Make sqlite column migration work

* Remove PostMigrations

These should be replaced with Notification usage

* Remove outer scope from Upgrader

* Remove unececary null check

* Add marker base class for migrations

* Enable scopeless migrations

* Remove unnecessary state check

The final state of the migration is no longer necessarily the final state of the plan.

* Extend ExecutedMigrationPlan

* Ensure that MigrationPlanExecutor.Execute always returns a result.

* Always save final state, regardless of errors

* Remove obsolete Execute

* Add Umbraco specific migration notification

* Publish notification after umbraco migration

* Throw the exception that failed a migration after publishing notification

* Handle notification publishing in DatabaseBuilder

* Fix tests

* Remember to complete scope

* Clean up MigrationPlanExecutor

* Run each package migration in a separate scope

* Add PartialMigrationsTests

* Add unhappy path test

* Fix bug shown by test

* Move PartialMigrationsTests into the correct folder

* Comment out refresh cache in data type migration

Need to add this back again as a notification handler or something.

* Start working on a notification test

* Allow migrations to request a cache rebuild

* Set RebuildCache from MigrateDataTypeConfigurations

* Clean MigrationPlanExecutor

* Add comment explaining the need to partial migration success

* Fix tests

* Allow overriding DefinePlan of UmbracoPlan

This is needed to test the DatabaseBuilder

* Fix notification test

* Don't throw exception to be immediately re-caught

* Assert that scopes notification are always published

* Ensure that scopes are created when requested

* Make test classes internal.

It doesn't really matter, but this way it doesn't show up in intellisense

* Add notification handler for clearing cookies

* Add CompatibilitySuppressions

* Use unscoped migration for adding GUID to user group

* Make sqlite migration work

It's really not pretty, square peg, round hole.

* Don't re-enable foreign keys

This will happen automatically next time a connection is started.

* Scope database when using SQLServer

* Don't call complete transaction

* Tidy up a couple of comment

* Only allow scoping the database from UnscopedMigrationBase

* Fix comment

* Remove remark in UnscopedMigrationBase as it's no longer true

* Add keys when creating default user groups

* Map database value from DTO to entity

* Fix migration

Rename also renamed the foreign keys, making it not work

* Make migration idempotent

* Fix unit test

* Update CompatibilitySuppressions.xml

* Add UniqueId to AppendGroupBy

Otherwise MSSQL grenades

* Cleanup

* Update CompatibilitySuppressions

* Rename UniqueId to Key

* Cleanup

---------

Co-authored-by: Elitsa Marinovska <elm@umbraco.dk>
2023-02-07 08:30:33 +01:00
kjac ad1797eb41 Clean up + add proprety type appearance 2023-02-06 11:11:24 +01:00
kjac c88d00797a Add URLs and template data to document view model 2023-02-04 13:21:34 +01:00
kjac 0d7d8edaae Obsolete more ILocalizationService usage 2023-02-04 13:20:01 +01:00
kjac 8c2fa7274c Add the remaining properties to document type (minus list view info, still pending) 2023-02-04 12:03:43 +01:00
kjac 43c10a7fc0 Expose content type key on ContentTypeSort 2023-02-04 12:02:58 +01:00
kjac 54e76b74c4 Handle unpublished, non-variant content 2023-02-02 09:29:36 +01:00
kjac d04c50b988 Basic structure for document and document type read API 2023-02-01 15:35:38 +01:00
Andreas ZerbstandAndreas Zerbst fdd059fb2b Updated the ID of the locator in the test 'can set a minimum of required blocks in content with a block list editor' to match the correct ID. (#13769) 2023-02-01 15:21:33 +01:00
70aa626991 Fix sln file for the new backoffice (#13765)
* Fix sln file and add README commands to get started

* expand the docs a bit

---------

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
2023-02-01 10:37:21 +01:00
8caee5297b Use ISO codes instead of language IDs for fallback languages and translations (#13751)
* Use language ISO code for language fallback instead of language ID

* Remove language and language ID from dictionary item and dictionary item translation

* ADd unit test for dictionary item translation value extension

* Make the internal service implementations sealed

* Rename translation ISO code to be more explicit in its origin (Language)

* Add breaking changes suppression

* Handle save of invalid fallback iso code

* Fixed test

* Only allow non-UserCustomCulture's

* Fixed and added tests

* Rename ISO code validation method

* Fix language telemetry test (create Swedish with the correct ISO code)

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-02-01 09:37:37 +01:00
Kenn JacobsenandGitHub 641cae7fb5 Align the data type API (#13760)
* Make data type CRUD operations async using Attempt pattern

* Refactor data type container management to its own service + add unit tests for it

* Add compatability suppression for new interface methods and unit test changes
2023-02-01 08:38:36 +01:00
Kenn JacobsenandGitHub ac8cfcf634 Align template API with dictionary API (#13714)
* Align the template services and API with the dictionary ones (use attempt pattern)

* A little controller clean-up

* Mimic old file service behavior, make unit tests happy

* Align CreateForContentTypeAsync return value with the rest of the TemplateService API

* Scaffold endpoint should no longer feature master templates

* Update the OpenAPI JSON
2023-01-31 12:20:46 +01:00
Bjarke Berg 5f8ef4cfff Merge remote-tracking branch 'origin/v12/dev' into v13/dev 2023-01-30 08:02:44 +01:00
Jacob Overgaard 219940f523 update backoffice submodule 2023-01-27 09:08:55 +01:00
Kenn JacobsenandGitHub 0297152249 Split localization service into dedicated services (#13731)
* Rework language service and API

* Revert unintended commit of Directory.Build.props

* Create OS conditional test for invalid ISO codes

* Reintroduce and obsolete old Delete method on ILocalizationService + make new Delete method delete by ISO code + add obsoletion attrs to service implementation

* Review comments + utilize new Delete method

* Do not allow model reuse when creating a new language

* Fix bad merge

* Split localization service into dedicated services for language and dictionary item handling

* Replaced ILocalizationService usage in management API (as much as can be done for now)

* Ensure we can create dictionary items with explicit keys (but no duplicates)

* Fix culture controller so it works properly with pagination

* Update OpenAPI JSON

* Actually update the language being updated...

* Unit test for invalid ISO now no longer needs to differ between OS :)

* A little bit of code health improvements

* A litte less code duplication

* Remove duplicate validation
2023-01-26 13:34:11 +01:00
aa90efa5b7 New Backoffice: Log viewer controller (#13648)
* Fixing a few nullable reference types for log viewer (#13634)

(cherry picked from commit b4ca2a6636)

* Adding LogControllerBase

* Migrating GetLogLevels()

* Migrating GetNumberOfErrors()

* Migrating GetLogLevelCounts()

* Migrating GetCanViewLogs()

* Migrating GetMessageTemplates()

* Migrating GetLogs()

* Migrating GetSavedSearches()

* Migrating PostSavedSearch()

* Migrating DeleteSavedSearch()

* Adding LoggerViewModel

* Adding LogViewModelMapDefinition

* Update OpenApi.json

* Cleanup

* V12: Change nullability for the log searches (#13647)

* Changing nullability

* Obsolete DeleteSavedSearch since the query param is not used

* Fix a bit more referenced

* Add default implementation for the new overload of DeleteSavedSearch

(cherry picked from commit 5e06f5a8a0)

* Updates based on nullability fix

* Adding GetSavedSearchByName

* Implementing ByName endpoint

* Refactoring Delete endpoint based on GetSavedSearchByName

* Refactoring Create endpoint to return the item's location

* Suppress new GetSavedSearchByName in ILogViewer interfaces

* Update OpenApi.json

* Adding github initials to FIXME

* Renaming

* Moving files to Core proj

* Adding GetLogs with skip and take

* Introducing ILogViewerService

* Supressing xml for ILogViewer.GetLogsAsPagedModel()

* Changing to our own Enum representation of LogLevel

* Creating ILogEntry needed for GetPagedLogs()

* Refactoring controllers to use the new logViewerService

* Removing base class methods since those have been moved to the new service

* Removing ErrorCountLogViewerController since the result can be calculated from another endpoint

* Refactoring the MapDefinition because of the new return types from the service

* Update OpenApi.json

* Obsoleting old methods in favor of the ILogViewerService

* Cleanup

* Fixing enum representation as strings for Swagger

* Adding documentation

* Changing enum representation to string in OpenApi.OpenApi.json

* Fix FIXME (use CreatedAtAction)

* Removing JsonStringEnumConverter as there should be another way to fix enum representation for Swagger

* Removing MappingBuilderExtensions and making specific LogViewerBuilderExtensions

* Changes to the .sln file

* Take only the result in the response

* Register the LogViewer extensions

* Update OpenApi.json

* Fix the supressions.xml

* Add inheritdoc

* Remove GetSavedSearchByName as it isn't necessary to introduce it anymore

* Obsolete interfaces

* Rename ViewPermission controller to ValidateLogFileSize

* Make rest of the methods async

* Route name change

* Remove methods obsoletion

* Introduce the "attempt" pattern

* Refactoring of ILogViewerService

* Refactoring controllers

* Another OpenApi.json update

* Adding fixme

* Re-add new client project

Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch>
2023-01-25 11:53:42 +01:00
Bjarke Berg 0fd90c1294 Merge remote-tracking branch 'origin/v12/dev' into v13/dev 2023-01-24 12:04:01 +01:00
Kenn JacobsenandGitHub ff2d90d775 Rework dictionary CRUD operations (#13688)
* Rework dictionary CRUD operations

* Update OpenAPI json

* Move responsibility to localization service, introduce new attempt pattern for create and update operations, update unit tests accordingly

* Fix merge

* Rollback assumption that we can map entities from scratch (entity relations got in the way)

* Update OpenAPI JSON

* Add breakage supressions

* Add compat suppressions for integration test project

* Make dictionary item deletion follow same pattern as create and update

* Review comments + update delete to use new pattern

* Update breakage suppressions to match the new Delete method
2023-01-20 13:40:24 +01:00
Bjarke Berg 4be798ddfb Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	src/Umbraco.Infrastructure/Install/PackageMigrationRunner.cs
#	src/Umbraco.Infrastructure/Migrations/IMigrationContext.cs
#	src/Umbraco.Infrastructure/Migrations/IMigrationPlanExecutor.cs
#	src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs
#	src/Umbraco.Infrastructure/Migrations/MigrationContext.cs
#	src/Umbraco.Infrastructure/Migrations/MigrationPlan.cs
#	src/Umbraco.Infrastructure/Migrations/MigrationPlanExecutor.cs
#	src/Umbraco.Infrastructure/Migrations/PostMigrations/ClearCsrfCookies.cs
#	src/Umbraco.Infrastructure/Migrations/PostMigrations/DeleteLogViewerQueryFile.cs
#	src/Umbraco.Infrastructure/Migrations/PostMigrations/RebuildPublishedSnapshot.cs
#	src/Umbraco.Infrastructure/Migrations/Upgrade/Upgrader.cs
#	src/Umbraco.Web.BackOffice/Controllers/MacroRenderingController.cs
#	tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Migrations/MigrationPlanTests.cs
#	tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Migrations/PostMigrationTests.cs
2023-01-19 10:43:07 +01:00
9c00c95f01 v13: New Backoffice in CMS (POC) (#13664)
* Added a new executeable to new backoffice

* add new backoffice client as submodule

* add new backoffice client as project

* add bootstrap of backoffice client

* experimentally allow CORS from local vite app running the backoffice

* fix base path

* move new backoffice projects to NewBackoffice folder

* add support for redirect urls to login page (temporary)

* update references to v13

* override databaseinstall/index.cshtml

* copy ignore lines from normal project

* remove redirect to AuthorizeUpgrade

* codeql: checkout submodules

* Section catch-all route

* fixed tests

* remove starter-kit file

* remove grid views

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-01-18 15:02:59 +01:00
Kenn JacobsenandGitHub 4640a317b8 Support non-nullable reference types in OpenAPI doc (#13685)
* Refactored ManagementApiComposer into several extension classes

* ADd support for non-nullable reference types in OpenAPI doc

* Update OpenAPI JSON to reflect new (lack of) nullability

* Don't add factories twice :)

* Rework composing + move backoffice route detection for management API to core
2023-01-18 13:11:42 +01:00
Elitsa MarinovskaandGitHub 2c8927c2e9 Rename old FIXME to TODO (#13646)
* Rename old FIXME to TODO, so we can track new FIXME starting v13

* Remove empty TODO
2023-01-18 12:28:54 +01:00
Kenn JacobsenandGitHub de8e307295 Add "is trashed" data for content and media tree controllers (#13687) 2023-01-17 14:04:22 +01:00
Kenn JacobsenandGitHub 25f66e7413 Turn the indexer health status into an enum + rearrange the view models according to controller namespaces (#13686) 2023-01-17 14:04:13 +01:00
13fb2a4f52 New Backoffice: Refactor migrations to allow for unscoped migrations (#13654)
* Remove PostMigrations

These should be replaced with Notification usage

* Remove outer scope from Upgrader

* Remove unececary null check

* Add marker base class for migrations

* Enable scopeless migrations

* Remove unnecessary state check

The final state of the migration is no longer necessarily the final state of the plan.

* Extend ExecutedMigrationPlan

* Ensure that MigrationPlanExecutor.Execute always returns a result.

* Always save final state, regardless of errors

* Remove obsolete Execute

* Add Umbraco specific migration notification

* Publish notification after umbraco migration

* Throw the exception that failed a migration after publishing notification

* Handle notification publishing in DatabaseBuilder

* Fix tests

* Remember to complete scope

* Clean up MigrationPlanExecutor

* Run each package migration in a separate scope

* Add PartialMigrationsTests

* Add unhappy path test

* Fix bug shown by test

* Move PartialMigrationsTests into the correct folder

* Comment out refresh cache in data type migration

Need to add this back again as a notification handler or something.

* Start working on a notification test

* Allow migrations to request a cache rebuild

* Set RebuildCache from MigrateDataTypeConfigurations

* Clean MigrationPlanExecutor

* Add comment explaining the need to partial migration success

* Fix tests

* Allow overriding DefinePlan of UmbracoPlan

This is needed to test the DatabaseBuilder

* Fix notification test

* Don't throw exception to be immediately re-caught

* Assert that scopes notification are always published

* Ensure that scopes are created when requested

* Make test classes internal.

It doesn't really matter, but this way it doesn't show up in intellisense

* Add notification handler for clearing cookies

* Add CompatibilitySuppressions

* Rename Execute to ExecutePlan

We have to do this to be able to obsolete :(

* Update CompatibilitySuppressions

* Update src/Umbraco.Infrastructure/Migrations/MigrationPlanExecutor.cs

Co-authored-by: Bjarke Berg <mail@bergmania.dk>

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-01-16 14:52:51 +01:00
01224fce89 Template API for new backoffice (#13642)
* Template query builder API

* Create a dedicated template service (copy template operations from file service)

* CRUD API for templates

* Make file service consume the template service (remove duplicated code)

* Use the template service in the old template controller so we can track changes better (note: this is breaking, but it doesn't matter as the controller will be deleted)

* Add scaffolding to the template API

* Make the route differ between query settings and execution

* Get rid of ugly string constants

* Refactor query execution a little to improve code health

* Fix build checks (compat)

* Deduce the master template from the template contents

* Make template service async, move master template parsing into template service

* Fix open API test

* Make sure the unit tests use new template parsing

* Add FIXME for SetMasterTemplate

* added obsolete attributes

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2023-01-11 14:40:41 +01:00
c81918c9ee Return true if connectionstring configured (#13640)
Signed-off-by: Zeegaan <nge@umbraco.dk>

Signed-off-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Zeegaan <nge@umbraco.dk>
2023-01-09 08:53:31 +01:00
Bjarke Berg 08c1708730 Merge remote-tracking branch 'origin/v12/dev' into v13/dev
# Conflicts:
#	src/Umbraco.Cms.Api.Management/Controllers/ManagementApiControllerBase.cs
2023-01-06 10:30:58 +01:00
c44fa56661 New backoffice: Data type API (#13633)
* Add PropertyEditorUiAlias to datatype incl. migration for persistence

* Add configuration validation

* Folder CRUD (reusable for other folder trees) + datatype delete + more RESTish response from datatype create and update

* API for datatype references

* Clean up response types, swagger metadata and fix OpenAPI test

* Allow breakage in the build

* Use yield return pattern

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* Fix incorrect return type from references API

Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2023-01-06 08:45:06 +01:00
Kenn JacobsenandGitHub a8f070d834 Datatype configuration refactor (#13605)
* Moved refactor from V12 based branch

* Remove obsolete config property to avoid obsoletion warnings

* Clean up test models

* Make the datatype API a little less confusing by introducing explicit models for create and update

* Remame "Configuration" to "Data" to make FE happy :)

* Safeguard deserialization of empty configs

* Less strict number handling for deserialization

* Prepare for data type config migrations

* Attempt to have contextual config serializers

* Update OpenAPI spec with (temporary) data type controller

* Fix unit tests

* Update compat suppressions (allow breakage for datatype and configuration editor)

* Make the duplicate JsonObjectConverter implementation private
2022-12-21 14:29:59 +01:00
2282 changed files with 122021 additions and 34602 deletions
+1
View File
@@ -1,3 +1,4 @@
**/*
!tests/Umbraco.Tests.Integration/bin/**
!tests/Umbraco.Tests.UnitTests/bin/**
**/node_modules
+23 -3
View File
@@ -5,14 +5,34 @@
This solution folder contains the projects for the new backoffice. If you're looking to fix or improve the existing CMS, this is not the place to do it, although we do very much appreciate your efforts.
### Getting Started: Management API
This branch contains the project for the new Management API as well as the new Backoffice. To get started with the Management API you should:
* Run any of the executables (Umbraco.Web.UI or Umbraco.Web.UI.New)
* Access "/umbraco/swagger" in the browser to see the Swagger interface
* The API lives in the Umbraco.Cms.Api.Management project
### Getting Started: Backoffice
To run the new Backoffice:
* Execute `git submodule init` and then `git submodule update` to get the files into Umbraco.Web.UI.New.Client project
* Run Umbraco.Web.UI.New project
* If you get a white page delete Umbraco.Cms.StaticAssets\wwwroot\umbraco folder and run `npm ci && npm run build:for:cms` inside Umbraco.Web.UI.New.Client folder to clear out any leftover files from older versions.
* If you are going to work on the Backoffice, you can either go to the Umbraco.Web.UI.New.Client folder and check out a new branch or set it up in your IDE, which will allow you to commit to each repository simultaneously:
* **Rider**: Preferences -> Version Control -> Directory Mappings -> Click the '+' sign
### Latest version
* If you want to get the latest changes from the Backoffice repository, run `git submodule update` again which will pull the latest main branch.
### Project structure
Since the new backoffice API is still very much a work in progress, we've created new projects for the new backoffice API:
* Umbrao.Cms.ManagementApi - The "presentation layer" for the management API
* "New" versions of existing projects, should be merged with the existing projects when the new API is released:
* Umbraco.New.Cms.Core
* Umbraco.New.Cms.Infrastructure
* Umbraco.New.Cms.Web.Common
* Umbraco.Cms.Core
* Umbraco.Cms.Infrastructure
* Umbraco.Cms.Web.Common
* Umbraco.Web.UI.New
* Umbraco.Web.UI.New.Client
This also means that we have to use "InternalsVisibleTo" for the new projects since these should be able to access the internal classes since they will when they get merged.
+2
View File
@@ -23,6 +23,7 @@ env:
DOTNET_GENERATE_ASPNET_CERTIFICATE: false
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
NODE_OPTIONS: --max_old_space_size=16384
jobs:
CodeQL-Build:
@@ -37,6 +38,7 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: true
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
+11 -5
View File
@@ -50,10 +50,6 @@ tools/docfx/
# Ignore rule for clearing out Belle (avoid rebuilding all the time)
preserve.belle
# Ignore rule for output of generated documentation files from grunt docserve
/src/Umbraco.Web.UI.Docs/api/
/src/Umbraco.Web.UI.Docs/package-lock.json
# csharp-docs
/build/csharp-docs/api/
/build/csharp-docs/_site/
@@ -68,7 +64,13 @@ preserve.belle
/build/docs.zip
/build/ui-docs.zip
/build/csharp-docs.zip
/src/Umbraco.Cms.StaticAssets/wwwroot/umbraco/
/src/Umbraco.Cms.StaticAssets/wwwroot/umbraco/auth
/src/Umbraco.Cms.StaticAssets/wwwroot/umbraco/backoffice
/src/Umbraco.Cms.StaticAssets/wwwroot/umbraco/assets
/src/Umbraco.Cms.StaticAssets/wwwroot/umbraco/js
/src/Umbraco.Cms.StaticAssets/wwwroot/umbraco/lib
/src/Umbraco.Cms.StaticAssets/wwwroot/umbraco/views
/src/Umbraco.Cms.StaticAssets/wwwroot/umbraco/login
# Environment specific data
/src/Umbraco.Web.UI.Client/[Bb]uild/
@@ -91,6 +93,7 @@ preserve.belle
# Tests
/tests/Umbraco.Tests.AcceptanceTest/.env
/tests/Umbraco.Tests.AcceptanceTest/playwright/.auth
/tests/Umbraco.Tests.Integration.SqlCe/DatabaseContextTests.sdf
/tests/Umbraco.Tests.Integration.SqlCe/[Uu]mbraco/[Dd]ata/TEMP/
/tests/Umbraco.Tests.Integration/appsettings.Tests.Local.json
@@ -103,10 +106,13 @@ preserve.belle
# Ignore auto-generated schema
/src/Umbraco.Cms.Targets/tasks/
/src/Umbraco.Cms.Targets/appsettings-schema.*.json
/src/Umbraco.Cms.Targets/umbraco-package-schema.json
/src/Umbraco.Web.UI/appsettings-schema.json
/src/Umbraco.Web.UI/appsettings-schema.*.json
/src/Umbraco.Web.UI/umbraco-package-schema.json
/tests/Umbraco.Tests.Integration/appsettings-schema.json
/tests/Umbraco.Tests.Integration/appsettings-schema.*.json
/tests/Umbraco.Tests.Integration/umbraco-package-schema.json
/src/Umbraco.Cms/appsettings-schema.json
playwright-report
trace.zip
+3
View File
@@ -0,0 +1,3 @@
[submodule "src/Umbraco.Web.UI.New.Client"]
path = src/Umbraco.Web.UI.New.Client
url = https://github.com/umbraco/Umbraco.CMS.Backoffice.git
+3 -3
View File
@@ -28,9 +28,9 @@
<!-- Package Validation -->
<PropertyGroup>
<GenerateCompatibilitySuppressionFile>false</GenerateCompatibilitySuppressionFile>
<EnablePackageValidation>true</EnablePackageValidation>
<PackageValidationBaselineVersion>13.0.0</PackageValidationBaselineVersion>
<GenerateCompatibilitySuppressionFile>true</GenerateCompatibilitySuppressionFile>
<EnablePackageValidation>false</EnablePackageValidation>
<PackageValidationBaselineVersion>14.0.0</PackageValidationBaselineVersion>
<EnableStrictModeForCompatibleFrameworksInPackage>true</EnableStrictModeForCompatibleFrameworksInPackage>
<EnableStrictModeForCompatibleTfms>true</EnableStrictModeForCompatibleTfms>
</PropertyGroup>
+5 -4
View File
@@ -19,6 +19,7 @@
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
@@ -32,7 +33,6 @@
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="8.0.0" />
<PackageVersion Include="System.Runtime.Caching" Version="8.0.0" />
</ItemGroup>
<!-- Umbraco packages -->
<ItemGroup>
@@ -41,12 +41,13 @@
</ItemGroup>
<!-- Third-party packages -->
<ItemGroup>
<PackageVersion Include="Asp.Versioning.Mvc" Version="7.1.1" />
<PackageVersion Include="Asp.Versioning.Mvc.ApiExplorer" Version="7.1.0" />
<PackageVersion Include="Asp.Versioning.Mvc" Version="8.0.0" />
<PackageVersion Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.0.0" />
<PackageVersion Include="Dazinator.Extensions.FileProviders" Version="2.0.0" />
<PackageVersion Include="Examine" Version="3.2.0" />
<PackageVersion Include="Examine.Core" Version="3.2.0" />
<PackageVersion Include="HtmlAgilityPack" Version="1.11.57" />
<PackageVersion Include="JsonPatch.Net" Version="2.1.0" />
<PackageVersion Include="K4os.Compression.LZ4" Version="1.3.6" />
<PackageVersion Include="MailKit" Version="4.3.0" />
<PackageVersion Include="Markdown" Version="2.2.1" />
@@ -89,4 +90,4 @@
<!-- Both Dazinator.Extensions.FileProviders and MiniProfiler.AspNetCore.Mvc bring in a vulnerable version of System.Text.RegularExpressions -->
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
</ItemGroup>
</Project>
</Project>
+139 -35
View File
@@ -17,6 +17,10 @@ parameters:
displayName: Deploy to NuGet
type: boolean
default: false
- name: npmDeploy
displayName: Deploy to Npm
type: boolean
default: false
- name: buildApiDocs
displayName: Build API docs
type: boolean
@@ -67,12 +71,15 @@ stages:
- stage: Build
variables:
npm_config_cache: $(Pipeline.Workspace)/.npm_client
NODE_OPTIONS: --max_old_space_size=16384
jobs:
- job: A
displayName: Build Umbraco CMS
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: self
submodules: true
- task: NodeTool@0
displayName: Use Node.js $(nodeVersion)
retryCountOnTaskFailure: 3
@@ -95,20 +102,21 @@ stages:
gulpFile: src/Umbraco.Web.UI.Client/gulpfile.js
targets: coreBuild
workingDirectory: src/Umbraco.Web.UI.Client
- task: npm@1
- script: npm ci --no-fund --no-audit --prefer-offline
displayName: Run npm ci (Login)
inputs:
command: custom
workingDir: src/Umbraco.Web.UI.Login
verbose: false
customCommand: ci
- task: npm@1
workingDirectory: src/Umbraco.Web.UI.Login
- script: npm run build
displayName: Run npm build (Login)
inputs:
command: custom
workingDir: src/Umbraco.Web.UI.Login
verbose: false
customCommand: run build
workingDirectory: src/Umbraco.Web.UI.Login
- script: npm ci --no-fund --no-audit --prefer-offline
displayName: Run npm ci (Bellissima)
workingDirectory: src/Umbraco.Web.UI.New.Client
- script: npm run build:for:cms
displayName: Run build (Bellissima)
workingDirectory: src/Umbraco.Web.UI.New.Client
- script: npm run build
displayName: Run Login Build (Bellissima)
workingDirectory: src/Umbraco.Web.UI.New.Client/apps/auth
- task: UseDotNet@2
displayName: Use .NET SDK from global.json
inputs:
@@ -135,6 +143,24 @@ stages:
inputs:
targetPath: $(Build.SourcesDirectory)
artifactName: build_output
- bash: |
echo "##[command]Running npm version"
echo "##[debug]Version: $PACKAGE_VERSION"
echo "##[command]Running npm pack"
echo "##[debug]Output directory: $(Build.ArtifactStagingDirectory)"
npm version $PACKAGE_VERSION --allow-same-version --no-git-tag-version
mkdir $(Build.ArtifactStagingDirectory)/npm
npm pack --pack-destination $(Build.ArtifactStagingDirectory)/npm
mv .npmrc $(Build.ArtifactStagingDirectory)/npm/
displayName: Prepare Bellissima npm package
env:
PACKAGE_VERSION: $(build.NBGV_NpmPackageVersion)
workingDirectory: src/Umbraco.Web.UI.New.Client
- task: PublishPipelineArtifact@1
displayName: Publish Bellissima npm artifact
inputs:
targetPath: $(Build.ArtifactStagingDirectory)/npm
artifactName: npm
- stage: Build_Docs
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.buildApiDocs}}))
@@ -150,10 +176,9 @@ stages:
vmImage: 'windows-latest'
steps:
- task: UseDotNet@2
displayName: Use .NET $(dotnetVersion)
displayName: Use .NET SDK from global.json
inputs:
version: $(dotnetVersion)
includePreviewVersions: $(dotnetIncludePreviewVersions)
useGlobalJson: true
- task: PowerShell@2
displayName: Install DocFX
inputs:
@@ -198,29 +223,41 @@ stages:
displayName: Build js API Reference
pool:
vmImage: 'ubuntu-latest'
variables:
npm_config_cache: $(Pipeline.Workspace)/.npm_client
NODE_OPTIONS: --max_old_space_size=16384
BASE_PATH: /v$(umbracoMajorVersion)/ui
steps:
- checkout: self
submodules: true
- task: NodeTool@0
displayName: Use Node.js 10.15.x
displayName: Use Node.js $(nodeVersion)
retryCountOnTaskFailure: 3
inputs:
versionSpec: 10.15.x # Won't work with higher versions
- script: |
npm ci --no-fund --no-audit --prefer-offline
npx gulp docs
major="$(umbracoMajorVersion)"
echo "major version: $major"
baseUrl="https://apidocs.umbraco.com/v$major/ui/"
echo "baseUrl: $baseUrl"
sed -i "s|baseUrl = .*|baseUrl = '$baseUrl',|" api/index.html
displayName: Generate js Docs
workingDirectory: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Docs
versionSpec: $(nodeVersion)
- task: Cache@2
displayName: Cache node_modules
inputs:
key: '"npm_client" | "$(Agent.OS)"| $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Client/package-lock.json | $(Build.SourcesDirectory)/src/Umbraco.Web.UI.New.Client/package-lock.json'
restoreKeys: |
"npm_client" | "$(Agent.OS)"
"npm_client"
path: $(npm_config_cache)
- script: npm ci --no-fund --no-audit --prefer-offline
workingDirectory: src/Umbraco.Web.UI.New.Client
displayName: Run npm ci
- script: npm run storybook:build
displayName: Build Storybook
env:
VITE_BASE_PATH: $(BASE_PATH)/
workingDirectory: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.New.Client
- script: sed -i "s|/umbraco/backoffice|$(BASE_PATH)/umbraco/backoffice|" assets/*.js
displayName: Replace BASE_PATH on assets
workingDirectory: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.New.Client/storybook-static
- task: ArchiveFiles@2
displayName: Archive js Docs
inputs:
rootFolderOrFile: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Docs/api
rootFolderOrFile: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.New.Client/storybook-static
includeRootFolder: false
archiveFile: $(Build.ArtifactStagingDirectory)/ui-docs.zip
- task: PublishPipelineArtifact@1
@@ -319,7 +356,7 @@ stages:
# Integration Tests (SQL Server)
- job:
timeoutInMinutes: 120
timeoutInMinutes: 180
condition: or(eq(stageDependencies.Build.A.outputs['build.NBGV_PublicRelease'], 'True'), ${{parameters.sqlServerIntegrationTests}})
displayName: Integration Tests (SQL Server)
strategy:
@@ -692,7 +729,7 @@ stages:
dependsOn:
- Unit
- Integration
# - E2E # TODO: Enable when stable.
# - E2E
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.myGetDeploy}}))
jobs:
- job:
@@ -714,6 +751,41 @@ stages:
publishFeedCredentials: 'MyGet - Umbraco Nightly'
${{ else }}:
publishFeedCredentials: 'MyGet - Pre-releases'
- job:
displayName: Push to pre-release feed (npm)
steps:
- checkout: none
- download: current
artifact: npm
- bash: |
# Check if we are on a nightly build
if [ $isNightly = "False" ]; then
echo "##[debug]Prerelease build detected"
registry="https://www.myget.org/F/umbracoprereleases/npm/"
else
echo "##[debug]Nightly build detected"
registry="https://www.myget.org/F/umbraconightly/npm/"
fi
echo "@umbraco-cms:registry=$registry" >> .npmrc
env:
isNightly: ${{parameters.isNightly}}
workingDirectory: $(Pipeline.Workspace)/npm
displayName: Add scoped registry to .npmrc
- task: npmAuthenticate@0
displayName: Authenticate with npm (MyGet)
inputs:
workingFile: '$(Pipeline.Workspace)/npm/.npmrc'
customEndpoint: 'MyGet (npm) - Umbracoprereleases, MyGet (npm) - Umbraconightly'
- bash: |
# Setup temp npm project to load in defaults from the local .npmrc
npm init -y
# Find the first .tgz file in the current directory and publish it
files=( ./*.tgz )
npm publish --access public "${files[0]}"
displayName: Push to npm (MyGet)
workingDirectory: $(Pipeline.Workspace)/npm
- stage: Deploy_NuGet
displayName: NuGet release
dependsOn:
@@ -738,15 +810,45 @@ stages:
nuGetFeedType: 'external'
publishFeedCredentials: 'NuGet - Umbraco.*'
- stage: Deploy_Npm
displayName: Npm release
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.npmDeploy}}))
dependsOn:
- Deploy_NuGet
jobs:
- job: Publish
displayName: Push to NPM
steps:
- checkout: none
- download: current
artifact: npm
- bash: echo "@umbraco-cms:registry=https://registry.npmjs.org" >> .npmrc
workingDirectory: $(Pipeline.Workspace)/npm
displayName: Add scoped registry to .npmrc
- task: npmAuthenticate@0
displayName: Authenticate with npm
inputs:
workingFile: $(Pipeline.Workspace)/npm/.npmrc
customEndpoint: 'NPM - Umbraco Backoffice'
- script: |
# Setup temp npm project to load in defaults from the local .npmrc
npm init -y
# Find the first .tgz file in the current directory and publish it
files=( ./*.tgz )
npm publish --tag $npmTag --access public "${files[0]}"
displayName: Push to npm
workingDirectory: $(Pipeline.Workspace)/npm
- stage: Upload_API_Docs
pool:
vmImage: 'windows-latest' # Apparently AzureFileCopy is windows only :(
variables:
umbracoMajorVersion: $[ stageDependencies.Build.A.outputs['build.NBGV_VersionMajor'] ]
displayName: Upload API Documention
displayName: Upload API Documentation
dependsOn:
- Build
- Deploy_NuGet
- Deploy_MyGet # Change to "Deploy_Nuget" after release of v14
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.uploadApiDocs}}))
jobs:
- job:
@@ -771,6 +873,7 @@ stages:
storage: umbracoapidocs
ContainerName: '$web'
BlobPrefix: v$(umbracoMajorVersion)/csharp
CleanTargetBeforeCopy: true
- job:
displayName: Upload js Docs
steps:
@@ -793,3 +896,4 @@ stages:
storage: umbracoapidocs
ContainerName: '$web'
BlobPrefix: v$(umbracoMajorVersion)/ui
CleanTargetBeforeCopy: true
@@ -0,0 +1,22 @@
namespace Umbraco.Cms.Api.Common.Attributes;
public abstract class ShortGenericSchemaNameAttribute : Attribute
{
public Type[] GenericTypes { get; set; }
public string SchemaName { get; set; }
public ShortGenericSchemaNameAttribute(string schemaName, Type[] genericTypes)
{
GenericTypes = genericTypes;
SchemaName = schemaName;
}
}
public class ShortGenericSchemaNameAttribute<T1, T2> : ShortGenericSchemaNameAttribute
{
public ShortGenericSchemaNameAttribute(string schemaName)
: base(schemaName, new[] { typeof(T1), typeof(T2) })
{
}
}
@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Common.Builders;
@@ -8,6 +9,8 @@ public class ProblemDetailsBuilder
private string? _title;
private string? _detail;
private string? _type;
private string? _operationStatus;
private IDictionary<string, object>? _extensions;
public ProblemDetailsBuilder WithTitle(string title)
{
@@ -27,11 +30,45 @@ public class ProblemDetailsBuilder
return this;
}
public ProblemDetails Build() =>
new()
public ProblemDetailsBuilder WithOperationStatus<TEnum>(TEnum operationStatus)
where TEnum : Enum
{
_operationStatus = operationStatus.ToString();
return this;
}
public ProblemDetailsBuilder WithRequestModelErrors(IDictionary<string, string[]> errors)
=> WithExtension(nameof(HttpValidationProblemDetails.Errors).ToFirstLowerInvariant(), errors);
public ProblemDetailsBuilder WithExtension(string key, object value)
{
_extensions ??= new Dictionary<string, object>();
_extensions[key] = value;
return this;
}
public ProblemDetails Build()
{
var problemDetails = new ProblemDetails
{
Title = _title,
Detail = _detail,
Type = _type ?? "Error",
};
if (_operationStatus is not null)
{
problemDetails.Extensions["operationStatus"] = _operationStatus;
}
if (_extensions is not null)
{
foreach (KeyValuePair<string, object> extension in _extensions)
{
problemDetails.Extensions[extension.Key] = extension.Value;
}
}
return problemDetails;
}
}
@@ -1,23 +1,22 @@
using System.Security.Cryptography;
using Microsoft.Extensions.DependencyInjection;
using System.Security.Cryptography;
using Microsoft.IdentityModel.Tokens;
using Umbraco.Cms.Api.Common.Security;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Infrastructure.BackgroundJobs.Jobs;
using Umbraco.Cms.Infrastructure.HostedServices;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Common.DependencyInjection;
public static class UmbracoBuilderAuthExtensions
{
private static bool _initialized;
public static IUmbracoBuilder AddUmbracoOpenIddict(this IUmbracoBuilder builder)
{
if (_initialized is false)
if (builder.Services.Any(x=>x.ImplementationType == typeof(OpenIddictCleanupJob)) is false)
{
ConfigureOpenIddict(builder);
_initialized = true;
}
return builder;
@@ -34,13 +33,17 @@ public static class UmbracoBuilderAuthExtensions
// FIXME: swap paths here so member API is first (see comment above)
options
.SetAuthorizationEndpointUris(
Paths.MemberApi.AuthorizationEndpoint.TrimStart(Constants.CharArrays.ForwardSlash))
Paths.MemberApi.AuthorizationEndpoint.TrimStart(Constants.CharArrays.ForwardSlash),
Paths.BackOfficeApi.AuthorizationEndpoint.TrimStart(Constants.CharArrays.ForwardSlash))
.SetTokenEndpointUris(
Paths.MemberApi.TokenEndpoint.TrimStart(Constants.CharArrays.ForwardSlash))
Paths.MemberApi.TokenEndpoint.TrimStart(Constants.CharArrays.ForwardSlash),
Paths.BackOfficeApi.TokenEndpoint.TrimStart(Constants.CharArrays.ForwardSlash))
.SetLogoutEndpointUris(
Paths.MemberApi.LogoutEndpoint.TrimStart(Constants.CharArrays.ForwardSlash))
Paths.MemberApi.LogoutEndpoint.TrimStart(Constants.CharArrays.ForwardSlash),
Paths.BackOfficeApi.LogoutEndpoint.TrimStart(Constants.CharArrays.ForwardSlash))
.SetRevocationEndpointUris(
Paths.MemberApi.RevokeEndpoint.TrimStart(Constants.CharArrays.ForwardSlash));
Paths.MemberApi.RevokeEndpoint.TrimStart(Constants.CharArrays.ForwardSlash),
Paths.BackOfficeApi.RevokeEndpoint.TrimStart(Constants.CharArrays.ForwardSlash));
// Enable authorization code flow with PKCE
options
@@ -101,6 +104,6 @@ public static class UmbracoBuilderAuthExtensions
options.UseDataProtection();
});
builder.Services.AddHostedService<OpenIddictCleanup>();
builder.Services.AddRecurringBackgroundJob<OpenIddictCleanupJob>();
}
}
@@ -0,0 +1,50 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core;
namespace Umbraco.Cms.Api.Common.Mvc.ActionResults;
/// <summary>
/// A "created at" action result with no response body.
/// </summary>
public sealed class EmptyCreatedAtActionResult : ActionResult
{
private readonly string _actionName;
private readonly string _controllerName;
private readonly object _routeValues;
private readonly string _resourceIdentifier;
public EmptyCreatedAtActionResult(string actionName, string controllerName, object routeValues, string resourceIdentifier)
{
_actionName = actionName;
_controllerName = controllerName;
_routeValues = routeValues;
_resourceIdentifier = resourceIdentifier;
}
public override void ExecuteResult(ActionContext context)
{
ArgumentNullException.ThrowIfNull(context);
HttpRequest request = context.HttpContext.Request;
IUrlHelper urlHelper = context.HttpContext.RequestServices.GetRequiredService<IUrlHelperFactory>().GetUrlHelper(context);
var url = urlHelper.Action(
_actionName,
_controllerName,
_routeValues,
request.Scheme,
request.Host.ToUriComponent());
if (string.IsNullOrEmpty(url))
{
throw new InvalidOperationException("No routes could be found that matched the provided route components");
}
context.HttpContext.Response.StatusCode = StatusCodes.Status201Created;
context.HttpContext.Response.Headers.Location = url;
context.HttpContext.Response.Headers[Constants.Headers.GeneratedResource] = _resourceIdentifier;
}
}
@@ -1,4 +1,5 @@
using System.Text.RegularExpressions;
using Umbraco.Cms.Api.Common.Attributes;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Common.OpenApi;
@@ -10,18 +11,9 @@ public class SchemaIdSelector : ISchemaIdSelector
protected string UmbracoSchemaId(Type type)
{
string SanitizedTypeName(Type t) => t.Name
// first grab the "non generic" part of any generic type name (i.e. "PagedViewModel`1" becomes "PagedViewModel")
.Split('`').First()
// then remove the "ViewModel" postfix from type names
.TrimEnd("ViewModel");
var name = SanitizedTypeName(type);
if (type.IsGenericType)
{
// append the generic type names, ultimately turning i.e. "PagedViewModel<RelationItemViewModel>" into "PagedRelationItem"
name = $"{name}{string.Join(string.Empty, type.GenericTypeArguments.Select(SanitizedTypeName))}";
}
name = HandleGenerics(name, type);
if (name.EndsWith("Model") == false)
{
@@ -33,4 +25,58 @@ public class SchemaIdSelector : ISchemaIdSelector
// make absolutely sure we don't pass any invalid named by removing all non-word chars
return Regex.Replace(name, @"[^\w]", string.Empty);
}
private string SanitizedTypeName(Type t) => t.Name
// first grab the "non generic" part of any generic type name (i.e. "PagedViewModel`1" becomes "PagedViewModel")
.Split('`').First()
// then remove the "ViewModel" postfix from type names
.TrimEnd("ViewModel");
private string HandleGenerics(string name, Type type)
{
if (!type.IsGenericType)
{
return name;
}
// find all types that implement this type and have an matching attribute
var assignableTypesWithAttributeInfo = AppDomain.CurrentDomain.GetAssemblies()
.Where(assembly => assembly.FullName?.StartsWith("Umbraco") == true)
.SelectMany(assembly => assembly.GetTypes())
.Where(t => t.IsAssignableTo(type))
.Select(t =>
{
var attribute = System.Attribute.GetCustomAttributes(t)
.FirstOrDefault(attribute => attribute is ShortGenericSchemaNameAttribute) as
ShortGenericSchemaNameAttribute;
return attribute == null
? new ShortSchemaNameAttributeInfo(t)
: new ShortSchemaNameAttributeInfo(t, attribute.GenericTypes, attribute.SchemaName);
})
.Where(info => info.GenericTypes != null);
var matchingType = assignableTypesWithAttributeInfo
.SingleOrDefault(t => t.GenericTypes!.Length == type.GenericTypeArguments.Length
&& t.GenericTypes.Intersect(type.GenericTypeArguments).Count() ==
type.GenericTypeArguments.Length && t.SchemaName.IsNullOrWhiteSpace() == false);
// use attribute custom name or append the generic type names, ultimately turning i.e. "PagedViewModel<RelationItemViewModel>" into "PagedRelationItem"
return matchingType != null
? matchingType.SchemaName!
: $"{name}{string.Join(string.Empty, type.GenericTypeArguments.Select(SanitizedTypeName))}";
}
private class ShortSchemaNameAttributeInfo
{
public Type Type { get; set; }
public Type[]? GenericTypes { get; set; }
public string? SchemaName { get; set; }
public ShortSchemaNameAttributeInfo(Type type, Type[]? genericTypes = null, string? schemaName = null)
{
Type = type;
GenericTypes = genericTypes;
SchemaName = schemaName;
}
}
}
@@ -62,6 +62,7 @@ public class SwaggerRouteTemplatePipelineFilter : UmbracoPipelineFilter
swaggerUiOptions.SwaggerEndpoint($"{name}/swagger.json", $"{apiInfo.Title}");
}
swaggerUiOptions.OAuthClientId(Constants.OAuthClientIds.Swagger);
swaggerUiOptions.OAuthUsePkce();
}
+16 -1
View File
@@ -1,7 +1,22 @@
namespace Umbraco.Cms.Api.Common.Security;
namespace Umbraco.Cms.Api.Common.Security;
public static class Paths
{
public static class BackOfficeApi
{
public const string EndpointTemplate = "security/back-office";
public static readonly string AuthorizationEndpoint = EndpointPath($"{EndpointTemplate}/authorize");
public static readonly string TokenEndpoint = EndpointPath($"{EndpointTemplate}/token");
public static readonly string LogoutEndpoint = EndpointPath($"{EndpointTemplate}/signout");
public static readonly string RevokeEndpoint = EndpointPath($"{EndpointTemplate}/revoke");
private static string EndpointPath(string relativePath) => $"/umbraco/management/api/v1/{relativePath}";
}
public static class MemberApi
{
public const string EndpointTemplate = "security/member";
@@ -22,7 +22,7 @@ public sealed class UmbracoJsonTypeInfoResolver : DefaultJsonTypeInfoResolver, I
return cachedResult;
}
var result = _typeFinder.FindClassesOfType(type).ToHashSet();
var result = _typeFinder.FindClassesOfType(type).OrderBy(x => x.Name).ToHashSet();
_subTypesCache.TryAdd(type, result);
return result;
}
@@ -9,6 +9,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Asp.Versioning.Mvc "/>
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" />
<PackageReference Include="Swashbuckle.AspNetCore" />
<PackageReference Include="OpenIddict.Abstractions" />
<PackageReference Include="OpenIddict.AspNetCore" />
@@ -17,5 +19,6 @@
<ItemGroup>
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj" />
<ProjectReference Include="..\Umbraco.Web.Common\Umbraco.Web.Common.csproj" />
</ItemGroup>
</Project>
@@ -1,35 +1,18 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core.DeliveryApi;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Delivery.Controllers.Content;
public abstract class ContentApiItemControllerBase : ContentApiControllerBase
{
// TODO: Remove this in V14 when the obsolete constructors have been removed
private readonly IPublicAccessService _publicAccessService;
[Obsolete($"Please use the constructor that does not accept {nameof(IPublicAccessService)}. Will be removed in V14.")]
protected ContentApiItemControllerBase(
IApiPublishedContentCache apiPublishedContentCache,
IApiContentResponseBuilder apiContentResponseBuilder,
IPublicAccessService publicAccessService)
: this(apiPublishedContentCache, apiContentResponseBuilder)
{
}
protected ContentApiItemControllerBase(
IApiPublishedContentCache apiPublishedContentCache,
IApiContentResponseBuilder apiContentResponseBuilder)
: base(apiPublishedContentCache, apiContentResponseBuilder)
=> _publicAccessService = StaticServiceProvider.Instance.GetRequiredService<IPublicAccessService>();
[Obsolete($"Please use {nameof(IPublicAccessService)} to test for content protection. Will be removed in V14.")]
protected bool IsProtected(IPublishedContent content) => _publicAccessService.IsProtected(content.Path);
{
}
protected async Task<IActionResult?> HandleMemberAccessAsync(IPublishedContent contentItem, IRequestMemberAccessService requestMemberAccessService)
{
@@ -1,16 +1,20 @@
using System.Net;
using Microsoft.AspNetCore.Mvc;
using System.Net;
using Microsoft.AspNetCore.Authorization;
using Umbraco.Cms.Api.Common.Attributes;
using Umbraco.Cms.Api.Common.Filters;
using Umbraco.Cms.Api.Delivery.Configuration;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Features;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Delivery.Controllers;
[ApiController]
[JsonOptionsName(Constants.JsonOptionsNames.DeliveryApi)]
[MapToApi(DeliveryApiConfiguration.ApiName)]
public abstract class DeliveryApiControllerBase : Controller
[Authorize(Policy = "New" + AuthorizationPolicies.UmbracoFeatureEnabled)]
public abstract class DeliveryApiControllerBase : Controller, IUmbracoFeature
{
protected string DecodePath(string path)
{
@@ -1,4 +1,4 @@
using System.Security.Claims;
using System.Security.Claims;
using Asp.Versioning;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Authentication;
@@ -1,4 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core;
@@ -1,4 +1,4 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OpenIddict.Abstractions;
using Umbraco.Cms.Core.Configuration.Models;
@@ -73,7 +73,7 @@ internal sealed class RevokeMemberAuthenticationTokensNotificationHandler
return;
}
_logger.LogInformation("Deleting {count} active tokens for member with ID {id}", tokens.Length, member.Id);
_logger.LogInformation("Revoking {count} active tokens for member with ID {id}", tokens.Length, member.Id);
foreach (var token in tokens)
{
await _tokenManager.DeleteAsync(token);
@@ -1,4 +1,4 @@
using OpenIddict.Abstractions;
using OpenIddict.Abstractions;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Security;
@@ -1,4 +1,4 @@
using System.Security.Claims;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
@@ -0,0 +1,61 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using Umbraco.Cms.Api.Common.Serialization;
using Umbraco.Cms.Api.Management.DependencyInjection;
using Umbraco.Cms.Api.Management.OpenApi;
namespace Umbraco.Cms.Api.Management.Configuration;
public class ConfigureUmbracoManagementApiSwaggerGenOptions : IConfigureOptions<SwaggerGenOptions>
{
private IUmbracoJsonTypeInfoResolver _umbracoJsonTypeInfoResolver;
public ConfigureUmbracoManagementApiSwaggerGenOptions(IUmbracoJsonTypeInfoResolver umbracoJsonTypeInfoResolver)
{
_umbracoJsonTypeInfoResolver = umbracoJsonTypeInfoResolver;
}
public void Configure(SwaggerGenOptions swaggerGenOptions)
{
swaggerGenOptions.SwaggerDoc(
ManagementApiConfiguration.ApiName,
new OpenApiInfo
{
Title = ManagementApiConfiguration.ApiTitle,
Version = "Latest",
Description = "This shows all APIs available in this version of Umbraco - including all the legacy apis that are available for backward compatibility",
});
swaggerGenOptions.OperationFilter<ResponseHeaderOperationFilter>();
swaggerGenOptions.SelectSubTypesUsing(_umbracoJsonTypeInfoResolver.FindSubTypes);
swaggerGenOptions.UseOneOfForPolymorphism();
swaggerGenOptions.UseAllOfForInheritance();
swaggerGenOptions.AddSecurityDefinition(
ManagementApiConfiguration.ApiSecurityName,
new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Name = "Umbraco",
Type = SecuritySchemeType.OAuth2,
Description = "Umbraco Authentication",
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl =
new Uri(Common.Security.Paths.BackOfficeApi.AuthorizationEndpoint, UriKind.Relative),
TokenUrl = new Uri(Common.Security.Paths.BackOfficeApi.TokenEndpoint, UriKind.Relative)
}
}
});
// Sets Security requirement on backoffice apis
swaggerGenOptions.OperationFilter<BackOfficeSecurityRequirementsOperationFilter>();
swaggerGenOptions.SchemaFilter<RequireNonNullablePropertiesSchemaFilter>();
}
}
@@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Routing;
namespace Umbraco.Cms.Api.Management.Controllers.AuditLog;
[ApiController]
[VersionedApiBackOfficeRoute("audit-log")]
[ApiExplorerSettings(GroupName = "Audit Log")]
public class AuditLogControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,43 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.AuditLogs;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.AuditLog;
[ApiVersion("1.0")]
[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessContentOrMedia)]
public class ByKeyAuditLogController : AuditLogControllerBase
{
private readonly IAuditService _auditService;
private readonly IAuditLogPresentationFactory _auditLogPresentationFactory;
public ByKeyAuditLogController(IAuditService auditService, IAuditLogPresentationFactory auditLogPresentationFactory)
{
_auditService = auditService;
_auditLogPresentationFactory = auditLogPresentationFactory;
}
[HttpGet("{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<AuditLogResponseModel>), StatusCodes.Status200OK)]
public async Task<IActionResult> ByKey(Guid id, Direction orderDirection = Direction.Descending, DateTime? sinceDate = null, int skip = 0, int take = 100)
{
PagedModel<IAuditItem> result = await _auditService.GetItemsByKeyAsync(id, skip, take, orderDirection, sinceDate);
IEnumerable<AuditLogResponseModel> mapped = _auditLogPresentationFactory.CreateAuditLogViewModel(result.Items);
var viewModel = new PagedViewModel<AuditLogResponseModel>
{
Total = result.Total,
Items = mapped,
};
return Ok(viewModel);
}
}
@@ -0,0 +1,39 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.AuditLogs;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.AuditLog;
[ApiVersion("1.0")]
public class ByTypeAuditLogController : AuditLogControllerBase
{
private readonly IAuditService _auditService;
private readonly IAuditLogPresentationFactory _auditLogPresentationFactory;
public ByTypeAuditLogController(IAuditService auditService, IAuditLogPresentationFactory auditLogPresentationFactory)
{
_auditService = auditService;
_auditLogPresentationFactory = auditLogPresentationFactory;
}
[HttpGet("type/{logType}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<AuditLogResponseModel>), StatusCodes.Status200OK)]
public async Task<IActionResult> ByType(AuditType logType, DateTime? sinceDate = null, int skip = 0, int take = 100)
{
IAuditItem[] result = _auditService.GetLogs(logType, sinceDate).ToArray();
IEnumerable<AuditLogResponseModel> mapped = _auditLogPresentationFactory.CreateAuditLogViewModel(result.Skip(skip).Take(take));
var viewModel = new PagedViewModel<AuditLogResponseModel>
{
Total = result.Length,
Items = mapped,
};
return await Task.FromResult(Ok(viewModel));
}
}
@@ -0,0 +1,65 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.AuditLogs;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Exceptions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.AuditLog;
[ApiVersion("1.0")]
public class CurrentUserAuditLogController : AuditLogControllerBase
{
private readonly IAuditService _auditService;
private readonly IAuditLogPresentationFactory _auditLogPresentationFactory;
private readonly IUserService _userService;
public CurrentUserAuditLogController(
IAuditService auditService,
IAuditLogPresentationFactory auditLogPresentationFactory,
IUserService userService)
{
_auditService = auditService;
_auditLogPresentationFactory = auditLogPresentationFactory;
_userService = userService;
}
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<AuditLogWithUsernameResponseModel>), StatusCodes.Status200OK)]
public async Task<IActionResult> CurrentUser(Direction orderDirection = Direction.Descending, DateTime? sinceDate = null, int skip = 0, int take = 100)
{
// FIXME: Pull out current backoffice user when its implemented.
// var userId = _backOfficeSecurityAccessor.BackOfficeSecurity?.GetUserId().Result ?? -1;
var userId = Constants.Security.SuperUserId;
IUser? user = _userService.GetUserById(userId);
if (user is null)
{
throw new PanicException("Could not find current user");
}
PagedModel<IAuditItem> result = await _auditService.GetPagedItemsByUserAsync(
user.Key,
skip,
take,
orderDirection,
null,
sinceDate);
IEnumerable<AuditLogWithUsernameResponseModel> mapped = _auditLogPresentationFactory.CreateAuditLogWithUsernameViewModels(result.Items);
var viewModel = new PagedViewModel<AuditLogWithUsernameResponseModel>
{
Total = result.Total,
Items = mapped,
};
return Ok(viewModel);
}
}
@@ -0,0 +1,54 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
namespace Umbraco.Cms.Api.Management;
[BindProperties]
public class
BackOfficeLoginModel
{
/// <summary>
/// Gets or sets the value of the "ReturnUrl" query parameter or defaults to the configured Umbraco directory.
/// </summary>
[FromQuery(Name = "ReturnUrl")]
public string? ReturnUrl { get; set; }
/// <summary>
/// The configured Umbraco directory.
/// </summary>
public string? UmbracoUrl { get; set; }
}
[ApiExplorerSettings(IgnoreApi=true)]
[Route("/umbraco/login")]
public class BackOfficeLoginController : Controller
{
private readonly IHostingEnvironment _hostingEnvironment;
private readonly GlobalSettings _globalSettings;
public BackOfficeLoginController(
IOptionsSnapshot<GlobalSettings> globalSettings,
IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
_globalSettings = globalSettings.Value ?? throw new ArgumentNullException(nameof(globalSettings));
}
// GET
public IActionResult Index(BackOfficeLoginModel model)
{
if (string.IsNullOrEmpty(model.UmbracoUrl))
{
model.UmbracoUrl = _hostingEnvironment.ToAbsolute(_globalSettings.UmbracoPath);
}
if (string.IsNullOrEmpty(model.ReturnUrl))
{
model.ReturnUrl = model.UmbracoUrl;
}
return View("/umbraco/UmbracoLogin/Index.cshtml", model);
}
}
@@ -0,0 +1,114 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.Content;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Models.ContentEditing.Validation;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Content;
public class ContentControllerBase : ManagementApiControllerBase
{
protected IActionResult ContentEditingOperationStatusResult(ContentEditingOperationStatus status)
=> OperationStatusResult(status, problemDetailsBuilder => status switch
{
ContentEditingOperationStatus.CancelledByNotification => BadRequest(problemDetailsBuilder
.WithTitle("Cancelled by notification")
.WithDetail("A notification handler prevented the content operation.")
.Build()),
ContentEditingOperationStatus.ContentTypeNotFound => NotFound(problemDetailsBuilder
.WithTitle("The requested content could not be found")
.Build()),
ContentEditingOperationStatus.ContentTypeCultureVarianceMismatch => BadRequest(problemDetailsBuilder
.WithTitle("Content type culture variance mismatch")
.WithDetail("The content type variance did not match that of the passed content data.")
.Build()),
ContentEditingOperationStatus.NotFound => NotFound(problemDetailsBuilder
.WithTitle("The content could not be found")
.Build()),
ContentEditingOperationStatus.ParentNotFound => NotFound(problemDetailsBuilder
.WithTitle("The targeted content parent could not be found")
.Build()),
ContentEditingOperationStatus.ParentInvalid => BadRequest(problemDetailsBuilder
.WithTitle("Invalid parent")
.WithDetail("The targeted parent was not valid for the operation.")
.Build()),
ContentEditingOperationStatus.NotAllowed => BadRequest(problemDetailsBuilder
.WithTitle("Operation not permitted")
.WithDetail(
"The attempted operation was not permitted, likely due to a permission/configuration mismatch with the operation.")
.Build()),
ContentEditingOperationStatus.TemplateNotFound => NotFound(problemDetailsBuilder
.WithTitle("The template could not be found")
.Build()),
ContentEditingOperationStatus.TemplateNotAllowed => BadRequest(problemDetailsBuilder
.WithTitle("Template not allowed")
.WithDetail("The selected template was not allowed for the operation.")
.Build()),
ContentEditingOperationStatus.PropertyTypeNotFound => NotFound(problemDetailsBuilder
.WithTitle("One or more property types could not be found")
.Build()),
ContentEditingOperationStatus.InTrash => BadRequest(problemDetailsBuilder
.WithTitle("Content is in the recycle bin")
.WithDetail("Could not perform the operation because the targeted content was in the recycle bin.")
.Build()),
ContentEditingOperationStatus.NotInTrash => BadRequest(problemDetailsBuilder
.WithTitle("Content is not in the recycle bin")
.WithDetail("The attempted operation requires the targeted content to be in the recycle bin.")
.Build()),
ContentEditingOperationStatus.SortingInvalid => BadRequest(problemDetailsBuilder
.WithTitle("Invalid sorting options")
.WithDetail("The supplied sorting operations were invalid. Additional details can be found in the log.")
.Build()),
ContentEditingOperationStatus.Unknown => StatusCode(
StatusCodes.Status500InternalServerError,
problemDetailsBuilder
.WithTitle("Unknown error. Please see the log for more details.")
.Build()),
_ => StatusCode(StatusCodes.Status500InternalServerError, problemDetailsBuilder
.WithTitle("Unknown content operation status.")
.Build()),
});
protected IActionResult ContentEditingOperationStatusResult<TContentModelBase, TValueModel, TVariantModel>(
ContentEditingOperationStatus status,
TContentModelBase requestModel,
ContentValidationResult validationResult)
where TContentModelBase : ContentModelBase<TValueModel, TVariantModel>
where TValueModel : ValueModelBase
where TVariantModel : VariantModelBase
{
if (status is not ContentEditingOperationStatus.PropertyValidationError)
{
return ContentEditingOperationStatusResult(status);
}
var errors = new SortedDictionary<string, string[]>();
var missingPropertyAliases = new List<string>();
foreach (PropertyValidationError validationError in validationResult.ValidationErrors)
{
TValueModel? requestValue = requestModel.Values.FirstOrDefault(value =>
value.Alias == validationError.Alias
&& value.Culture == validationError.Culture
&& value.Segment == validationError.Segment);
if (requestValue is null)
{
missingPropertyAliases.Add(validationError.Alias);
continue;
}
var index = requestModel.Values.IndexOf(requestValue);
var key = $"$.{nameof(ContentModelBase<TValueModel, TVariantModel>.Values).ToFirstLowerInvariant()}[{index}].{nameof(ValueModelBase.Value).ToFirstLowerInvariant()}{validationError.JsonPath}";
errors.Add(key, validationError.ErrorMessages);
}
return OperationStatusResult(status, problemDetailsBuilder
=> BadRequest(problemDetailsBuilder
.WithTitle("Validation failed")
.WithDetail("One or more properties did not pass validation")
.WithRequestModelErrors(errors)
.WithExtension("missingProperties", missingPropertyAliases.ToArray())
.Build()));
}
}
@@ -0,0 +1,40 @@
using System.Globalization;
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Api.Management.ViewModels.Culture;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
namespace Umbraco.Cms.Api.Management.Controllers.Culture;
[ApiVersion("1.0")]
public class AllCultureController : CultureControllerBase
{
private readonly IUmbracoMapper _umbracoMapper;
public AllCultureController(IUmbracoMapper umbracoMapper) => _umbracoMapper = umbracoMapper;
/// <summary>
/// Returns all cultures available for creating languages.
/// </summary>
/// <returns></returns>
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<CultureReponseModel>), StatusCodes.Status200OK)]
public async Task<PagedViewModel<CultureReponseModel>> GetAll(int skip = 0, int take = 100)
{
CultureInfo[] all = CultureInfo.GetCultures(CultureTypes.AllCultures)
.DistinctBy(x => x.Name)
.OrderBy(x => x.EnglishName)
.ToArray();
var viewModel = new PagedViewModel<CultureReponseModel>
{
Items = _umbracoMapper.MapEnumerable<CultureInfo, CultureReponseModel>(all.Skip(skip).Take(take)),
Total = all.Length
};
return await Task.FromResult(viewModel);
}
}
@@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Routing;
namespace Umbraco.Cms.Api.Management.Controllers.Culture;
[ApiController]
[VersionedApiBackOfficeRoute("culture")]
[ApiExplorerSettings(GroupName = "Culture")]
public abstract class CultureControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,37 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.DataType;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
[ApiVersion("1.0")]
public class ByKeyDataTypeController : DataTypeControllerBase
{
private readonly IDataTypeService _dataTypeService;
private readonly IUmbracoMapper _umbracoMapper;
public ByKeyDataTypeController(IDataTypeService dataTypeService, IUmbracoMapper umbracoMapper)
{
_dataTypeService = dataTypeService;
_umbracoMapper = umbracoMapper;
}
[HttpGet("{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(DataTypeResponseModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> ByKey(Guid id)
{
IDataType? dataType = await _dataTypeService.GetAsync(id);
if (dataType == null)
{
return DataTypeNotFound();
}
return Ok(_umbracoMapper.Map<DataTypeResponseModel>(dataType));
}
}
@@ -0,0 +1,28 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Api.Management.ViewModels.DataType;
using Umbraco.Cms.Core.Configuration.Models;
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
[ApiVersion("1.0")]
public class ConfigurationDataTypeController : DataTypeControllerBase
{
private readonly DataTypesSettings _dataTypesSettings;
public ConfigurationDataTypeController(IOptionsSnapshot<DataTypesSettings> dataTypesSettings) => _dataTypesSettings = dataTypesSettings.Value;
[HttpGet("configuration")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(DatatypeConfigurationResponseModel), StatusCodes.Status200OK)]
public Task<IActionResult> Configuration()
{
var responseModel = new DatatypeConfigurationResponseModel
{
CanBeChanged = _dataTypesSettings.CanBeChanged,
};
return Task.FromResult<IActionResult>(Ok());
}
}
@@ -0,0 +1,43 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.DataType;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
[ApiVersion("1.0")]
public class CopyDataTypeController : DataTypeControllerBase
{
private readonly IDataTypeService _dataTypeService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public CopyDataTypeController(IDataTypeService dataTypeService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_dataTypeService = dataTypeService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPost("{id:guid}/copy")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Copy(Guid id, CopyDataTypeRequestModel copyDataTypeRequestModel)
{
IDataType? source = await _dataTypeService.GetAsync(id);
if (source is null)
{
return DataTypeNotFound();
}
Attempt<IDataType, DataTypeOperationStatus> result = await _dataTypeService.CopyAsync(source, copyDataTypeRequestModel.Target?.Id, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? CreatedAtId<ByKeyDataTypeController>(controller => nameof(controller.ByKey), result.Result.Key)
: DataTypeOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,52 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.DataType;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
[ApiVersion("1.0")]
public class CreateDataTypeController : DataTypeControllerBase
{
private readonly IDataTypeService _dataTypeService;
private readonly IDataTypePresentationFactory _dataTypePresentationFactory;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public CreateDataTypeController(IDataTypeService dataTypeService, IDataTypePresentationFactory dataTypePresentationFactory, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_dataTypeService = dataTypeService;
_dataTypePresentationFactory = dataTypePresentationFactory;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPost]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Create(CreateDataTypeRequestModel createDataTypeRequestModel)
{
var attempt = await _dataTypePresentationFactory.CreateAsync(createDataTypeRequestModel);
if (!attempt.Success)
{
return DataTypeOperationStatusResult(attempt.Status);
}
Attempt<IDataType, DataTypeOperationStatus> result = await _dataTypeService.CreateAsync(attempt.Result, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? CreatedAtId<ByKeyDataTypeController>(controller => nameof(controller.ByKey), result.Result.Key)
: DataTypeOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,57 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.Builders;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
[ApiController]
[VersionedApiBackOfficeRoute(Constants.UdiEntityType.DataType)]
[ApiExplorerSettings(GroupName = "Data Type")]
[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)]
public abstract class DataTypeControllerBase : ManagementApiControllerBase
{
protected IActionResult DataTypeOperationStatusResult(DataTypeOperationStatus status) =>
status switch
{
DataTypeOperationStatus.InvalidConfiguration => BadRequest(new ProblemDetailsBuilder()
.WithTitle("Invalid data type configuration")
.WithDetail("The supplied data type configuration was not valid. Please see the log for more details.")
.Build()),
DataTypeOperationStatus.NotFound => DataTypeNotFound(),
DataTypeOperationStatus.InvalidName => BadRequest(new ProblemDetailsBuilder()
.WithTitle("Invalid data type name")
.WithDetail("The data type name must be non-empty and no longer than 255 characters.")
.Build()),
DataTypeOperationStatus.ParentNotContainer => BadRequest(new ProblemDetailsBuilder()
.WithTitle("parent id is not a container")
.WithDetail("The parent id does not represent a container.")
.Build()),
DataTypeOperationStatus.DuplicateKey => BadRequest(new ProblemDetailsBuilder()
.WithTitle("The id is already used")
.WithDetail("The data type id must be unique.")
.Build()),
DataTypeOperationStatus.CancelledByNotification => BadRequest(new ProblemDetailsBuilder()
.WithTitle("Cancelled by notification")
.WithDetail("A notification handler prevented the data type operation.")
.Build()),
DataTypeOperationStatus.PropertyEditorNotFound => NotFound(
new ProblemDetailsBuilder()
.WithTitle("The targeted property editor was not found.")
.Build()),
DataTypeOperationStatus.ParentNotFound => NotFound(new ProblemDetailsBuilder()
.WithTitle("The targeted parent for the data type operation was not found.")
.Build()),
_ => StatusCode(StatusCodes.Status500InternalServerError, new ProblemDetailsBuilder()
.WithTitle("Unknown data type operation status.")
.Build()),
};
protected IActionResult DataTypeNotFound() => NotFound(new ProblemDetailsBuilder()
.WithTitle("The data type could not be found")
.Build());
}
@@ -0,0 +1,37 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
[ApiVersion("1.0")]
public class DeleteDataTypeController : DataTypeControllerBase
{
private readonly IDataTypeService _dataTypeService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public DeleteDataTypeController(IDataTypeService dataTypeService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_dataTypeService = dataTypeService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpDelete("{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Delete(Guid id)
{
Attempt<IDataType?, DataTypeOperationStatus> result = await _dataTypeService.DeleteAsync(id, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: DataTypeOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,25 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.Folder;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
[ApiVersion("1.0")]
public class ByKeyDataTypeFolderController : DataTypeFolderControllerBase
{
public ByKeyDataTypeFolderController(
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
IDataTypeContainerService dataTypeContainerService)
: base(backOfficeSecurityAccessor, dataTypeContainerService)
{
}
[HttpGet("{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(FolderResponseModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> ByKey(Guid id) => await GetFolderAsync(id);
}
@@ -0,0 +1,29 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.Folder;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
[ApiVersion("1.0")]
public class CreateDataTypeFolderController : DataTypeFolderControllerBase
{
public CreateDataTypeFolderController(
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
IDataTypeContainerService dataTypeContainerService)
: base(backOfficeSecurityAccessor, dataTypeContainerService)
{
}
[HttpPost]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Create(CreateFolderRequestModel createFolderRequestModel)
=> await CreateFolderAsync<ByKeyDataTypeFolderController>(
createFolderRequestModel,
controller => nameof(controller.ByKey));
}
@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.DataType}/folder")]
[ApiExplorerSettings(GroupName = "Data Type")]
[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentTypes)]
public abstract class DataTypeFolderControllerBase : FolderManagementControllerBase<IDataType>
{
protected DataTypeFolderControllerBase(
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
IDataTypeContainerService dataTypeContainerService)
: base(backOfficeSecurityAccessor, dataTypeContainerService)
{
}
}
@@ -0,0 +1,25 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
[ApiVersion("1.0")]
public class DeleteDataTypeFolderController : DataTypeFolderControllerBase
{
public DeleteDataTypeFolderController(
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
IDataTypeContainerService dataTypeContainerService)
: base(backOfficeSecurityAccessor, dataTypeContainerService)
{
}
[HttpDelete("{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Delete(Guid id) => await DeleteFolderAsync(id);
}
@@ -0,0 +1,27 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.Folder;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
[ApiVersion("1.0")]
public class UpdateDataTypeFolderController : DataTypeFolderControllerBase
{
public UpdateDataTypeFolderController(
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
IDataTypeContainerService dataTypeContainerService)
: base(backOfficeSecurityAccessor, dataTypeContainerService)
{
}
[HttpPut("{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Update(Guid id, UpdateFolderResponseModel updateFolderResponseModel)
=> await UpdateFolderAsync(id, updateFolderResponseModel);
}
@@ -0,0 +1,32 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
[ApiVersion("1.0")]
public class IsUsedDataTypeController : DataTypeControllerBase
{
private readonly IDataTypeUsageService _dataTypeUsageService;
public IsUsedDataTypeController(IDataTypeUsageService dataTypeUsageService)
{
_dataTypeUsageService = dataTypeUsageService;
}
[HttpGet("{id:guid}/is-used")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> IsUsed(Guid id)
{
Attempt<bool, DataTypeOperationStatus> result = await _dataTypeUsageService.HasSavedValuesAsync(id);
return result.Success
? Ok(result.Result)
: DataTypeOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,34 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.DataType.Item;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Item;
[ApiVersion("1.0")]
public class ByEditorUiAliasController : DatatypeItemControllerBase
{
private readonly IDataTypeService _dataTypeService;
private readonly IUmbracoMapper _mapper;
public ByEditorUiAliasController(
IDataTypeService dataTypeService,
IUmbracoMapper mapper)
{
_dataTypeService = dataTypeService;
_mapper = mapper;
}
[HttpGet("{*alias}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(DataTypeItemResponseModel), StatusCodes.Status200OK)]
public async Task<IActionResult> ByEditorUiAlias(string alias)
{
IEnumerable<IDataType> dataTypes = await _dataTypeService.GetByEditorUiAlias(alias);
List<DataTypeItemResponseModel> responseModels = _mapper.MapEnumerable<IDataType, DataTypeItemResponseModel>(dataTypes);
return Ok(responseModels);
}
}
@@ -0,0 +1,15 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Core;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Item;
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.DataType}")]
[ApiExplorerSettings(GroupName = "Data Type")]
[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)]
public class DatatypeItemControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,41 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.DataType.Item;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Item;
[ApiVersion("1.0")]
public class ItemDatatypeItemController : DatatypeItemControllerBase
{
private readonly IDataTypeService _dataTypeService;
private readonly IUmbracoMapper _mapper;
public ItemDatatypeItemController(IDataTypeService dataTypeService, IUmbracoMapper mapper)
{
_dataTypeService = dataTypeService;
_mapper = mapper;
}
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<DataTypeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Item([FromQuery(Name = "id")] HashSet<Guid> ids)
{
var dataTypes = new List<IDataType>();
foreach (Guid id in ids)
{
IDataType? dataType = await _dataTypeService.GetAsync(id);
if (dataType is not null)
{
dataTypes.Add(dataType);
}
}
List<DataTypeItemResponseModel> responseModels = _mapper.MapEnumerable<IDataType, DataTypeItemResponseModel>(dataTypes);
return Ok(responseModels);
}
}
@@ -0,0 +1,43 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.DataType;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
[ApiVersion("1.0")]
public class MoveDataTypeController : DataTypeControllerBase
{
private readonly IDataTypeService _dataTypeService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public MoveDataTypeController(IDataTypeService dataTypeService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_dataTypeService = dataTypeService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPut("{id:guid}/move")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Move(Guid id, MoveDataTypeRequestModel moveDataTypeRequestModel)
{
IDataType? source = await _dataTypeService.GetAsync(id);
if (source is null)
{
return DataTypeNotFound();
}
Attempt<IDataType, DataTypeOperationStatus> result = await _dataTypeService.MoveAsync(source, moveDataTypeRequestModel.Target?.Id, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: DataTypeOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,39 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.DataType;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
[ApiVersion("1.0")]
public class ReferencesDataTypeController : DataTypeControllerBase
{
private readonly IDataTypeService _dataTypeService;
private readonly IDataTypeReferencePresentationFactory _dataTypeReferencePresentationFactory;
public ReferencesDataTypeController(IDataTypeService dataTypeService, IDataTypeReferencePresentationFactory dataTypeReferencePresentationFactory)
{
_dataTypeService = dataTypeService;
_dataTypeReferencePresentationFactory = dataTypeReferencePresentationFactory;
}
[HttpGet("{id:guid}/references")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(DataTypeReferenceResponseModel[]), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> References(Guid id)
{
Attempt<IReadOnlyDictionary<Udi, IEnumerable<string>>, DataTypeOperationStatus> result = await _dataTypeService.GetReferencesAsync(id);
if (result.Success == false)
{
return DataTypeOperationStatusResult(result.Status);
}
DataTypeReferenceResponseModel[] viewModels = _dataTypeReferencePresentationFactory.CreateDataTypeReferenceViewModels(result.Result).ToArray();
return Ok(viewModels);
}
}
@@ -0,0 +1,26 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels.DataType.Item;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
[ApiVersion("1.0")]
public class ChildrenDataTypeTreeController : DataTypeTreeControllerBase
{
public ChildrenDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
: base(entityService, dataTypeService)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DataTypeTreeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DataTypeTreeItemResponseModel>>> Children(Guid parentId, int skip = 0, int take = 100, bool foldersOnly = false)
{
RenderFoldersOnly(foldersOnly);
return await GetChildren(parentId, skip, take);
}
}
@@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.Controllers.Tree;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Api.Management.ViewModels.DataType.Item;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.DataType}")]
[ApiExplorerSettings(GroupName = "Data Type")]
[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDataTypes)]
public class DataTypeTreeControllerBase : FolderTreeControllerBase<DataTypeTreeItemResponseModel>
{
private readonly IDataTypeService _dataTypeService;
public DataTypeTreeControllerBase(IEntityService entityService, IDataTypeService dataTypeService)
: base(entityService) =>
_dataTypeService = dataTypeService;
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.DataType;
protected override UmbracoObjectTypes FolderObjectType => UmbracoObjectTypes.DataTypeContainer;
protected override DataTypeTreeItemResponseModel[] MapTreeItemViewModels(Guid? parentId, IEntitySlim[] entities)
{
var dataTypes = _dataTypeService
.GetAllAsync(entities.Select(entity => entity.Key).ToArray()).GetAwaiter().GetResult()
.ToDictionary(contentType => contentType.Id);
return entities.Select(entity =>
{
DataTypeTreeItemResponseModel responseModel = MapTreeItemViewModel(parentId, entity);
if (dataTypes.TryGetValue(entity.Id, out IDataType? dataType))
{
responseModel.EditorUiAlias = dataType.EditorUiAlias;
}
return responseModel;
}).ToArray();
}
}
@@ -0,0 +1,27 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels.DataType.Item;
using Umbraco.Cms.Api.Management.ViewModels.Tree;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
[ApiVersion("1.0")]
public class RootDataTypeTreeController : DataTypeTreeControllerBase
{
public RootDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
: base(entityService, dataTypeService)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DataTypeTreeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DataTypeTreeItemResponseModel>>> Root(int skip = 0, int take = 100, bool foldersOnly = false)
{
RenderFoldersOnly(foldersOnly);
return await GetRoot(skip, take);
}
}
@@ -0,0 +1,52 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.DataType;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.DataType;
[ApiVersion("1.0")]
public class UpdateDataTypeController : DataTypeControllerBase
{
private readonly IDataTypeService _dataTypeService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
private IDataTypePresentationFactory _dataTypePresentationFactory;
public UpdateDataTypeController(IDataTypeService dataTypeService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor, IDataTypePresentationFactory dataTypePresentationFactory)
{
_dataTypeService = dataTypeService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
_dataTypePresentationFactory = dataTypePresentationFactory;
}
[HttpPut("{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Update(Guid id, UpdateDataTypeRequestModel updateDataTypeViewModel)
{
IDataType? current = await _dataTypeService.GetAsync(id);
if (current == null)
{
return DataTypeNotFound();
}
Attempt<IDataType, DataTypeOperationStatus> attempt = await _dataTypePresentationFactory.CreateAsync(updateDataTypeViewModel, current);
if (!attempt.Success)
{
return DataTypeOperationStatusResult(attempt.Status);
}
Attempt<IDataType, DataTypeOperationStatus> result = await _dataTypeService.UpdateAsync(attempt.Result, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: DataTypeOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,39 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Core;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
[ApiVersion("1.0")]
public class AllDictionaryController : DictionaryControllerBase
{
private readonly IDictionaryItemService _dictionaryItemService;
private readonly IUmbracoMapper _umbracoMapper;
public AllDictionaryController(IDictionaryItemService dictionaryItemService, IUmbracoMapper umbracoMapper)
{
_dictionaryItemService = dictionaryItemService;
_umbracoMapper = umbracoMapper;
}
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DictionaryOverviewResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DictionaryOverviewResponseModel>>> All(int skip = 0, int take = 100)
{
// unfortunately we can't paginate here...we'll have to get all and paginate in memory
IDictionaryItem[] items = (await _dictionaryItemService.GetDescendantsAsync(Constants.System.RootKey)).ToArray();
var model = new PagedViewModel<DictionaryOverviewResponseModel>
{
Total = items.Length,
Items = _umbracoMapper.MapEnumerable<IDictionaryItem, DictionaryOverviewResponseModel>(items.Skip(skip).Take(take))
};
return await Task.FromResult(model);
}
}
@@ -0,0 +1,37 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
[ApiVersion("1.0")]
public class ByKeyDictionaryController : DictionaryControllerBase
{
private readonly IDictionaryItemService _dictionaryItemService;
private readonly IDictionaryPresentationFactory _dictionaryPresentationFactory;
public ByKeyDictionaryController(IDictionaryItemService dictionaryItemService, IDictionaryPresentationFactory dictionaryPresentationFactory)
{
_dictionaryItemService = dictionaryItemService;
_dictionaryPresentationFactory = dictionaryPresentationFactory;
}
[HttpGet($"{{{nameof(id)}:guid}}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(DictionaryItemResponseModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> ByKey(Guid id)
{
IDictionaryItem? dictionary = await _dictionaryItemService.GetAsync(id);
if (dictionary == null)
{
return DictionaryNotFound();
}
return Ok(await _dictionaryPresentationFactory.CreateDictionaryItemViewModelAsync(dictionary));
}
}
@@ -0,0 +1,65 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.Security.Authorization.Dictionary;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
[ApiVersion("1.0")]
public class CreateDictionaryController : DictionaryControllerBase
{
private readonly IDictionaryItemService _dictionaryItemService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
private readonly IDictionaryPresentationFactory _dictionaryPresentationFactory;
private readonly IAuthorizationService _authorizationService;
public CreateDictionaryController(
IDictionaryItemService dictionaryItemService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
IDictionaryPresentationFactory dictionaryPresentationFactory,
IAuthorizationService authorizationService)
{
_dictionaryItemService = dictionaryItemService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
_dictionaryPresentationFactory = dictionaryPresentationFactory;
_authorizationService = authorizationService;
}
[HttpPost]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status409Conflict)]
public async Task<IActionResult> Create(CreateDictionaryItemRequestModel createDictionaryItemRequestModel)
{
IDictionaryItem created = await _dictionaryPresentationFactory.MapCreateModelToDictionaryItemAsync(createDictionaryItemRequestModel);
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
new DictionaryPermissionResource(createDictionaryItemRequestModel.Translations.Select(t => t.IsoCode)),
AuthorizationPolicies.DictionaryPermissionByResource);
if (authorizationResult.Succeeded is false)
{
return Forbidden();
}
Attempt<IDictionaryItem, DictionaryItemOperationStatus> result =
await _dictionaryItemService.CreateAsync(created, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? CreatedAtId<ByKeyDictionaryController>(controller => nameof(controller.ByKey), result.Result!.Key)
: DictionaryItemOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,37 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
[ApiVersion("1.0")]
public class DeleteDictionaryController : DictionaryControllerBase
{
private readonly IDictionaryItemService _dictionaryItemService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public DeleteDictionaryController(IDictionaryItemService dictionaryItemService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_dictionaryItemService = dictionaryItemService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpDelete($"{{{nameof(id)}:guid}}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Delete(Guid id)
{
Attempt<IDictionaryItem?, DictionaryItemOperationStatus> result = await _dictionaryItemService.DeleteAsync(id, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: DictionaryItemOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,45 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.Builders;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
[ApiController]
[VersionedApiBackOfficeRoute("dictionary")]
[ApiExplorerSettings(GroupName = "Dictionary")]
[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDictionary)]
public abstract class DictionaryControllerBase : ManagementApiControllerBase
{
protected IActionResult DictionaryItemOperationStatusResult(DictionaryItemOperationStatus status) =>
status switch
{
DictionaryItemOperationStatus.DuplicateItemKey => Conflict(new ProblemDetailsBuilder()
.WithTitle("Duplicate dictionary item name detected")
.WithDetail("Another dictionary item exists with the same name. Dictionary item names must be unique.")
.Build()),
DictionaryItemOperationStatus.ItemNotFound => DictionaryNotFound(),
DictionaryItemOperationStatus.ParentNotFound => NotFound(new ProblemDetailsBuilder()
.WithTitle("The dictionary item parent could not be found")
.Build()),
DictionaryItemOperationStatus.CancelledByNotification => BadRequest(new ProblemDetailsBuilder()
.WithTitle("Cancelled by notification")
.WithDetail("A notification handler prevented the dictionary item operation.")
.Build()),
DictionaryItemOperationStatus.InvalidParent => BadRequest(new ProblemDetailsBuilder()
.WithTitle("Invalid parent")
.WithDetail("The targeted parent dictionary item is not valid for this dictionary item operation.")
.Build()),
_ => StatusCode(StatusCodes.Status500InternalServerError, new ProblemDetailsBuilder()
.WithTitle("Unknown dictionary operation status.")
.Build()),
};
protected IActionResult DictionaryNotFound() => NotFound(new ProblemDetailsBuilder()
.WithTitle("The dictionary item could not be found")
.Build());
}
@@ -0,0 +1,41 @@
using System.Net.Mime;
using System.Text;
using System.Xml.Linq;
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
[ApiVersion("1.0")]
public class ExportDictionaryController : DictionaryControllerBase
{
private readonly IDictionaryItemService _dictionaryItemService;
private readonly IEntityXmlSerializer _entityXmlSerializer;
public ExportDictionaryController(IDictionaryItemService dictionaryItemService, IEntityXmlSerializer entityXmlSerializer)
{
_dictionaryItemService = dictionaryItemService;
_entityXmlSerializer = entityXmlSerializer;
}
[HttpGet("{id:guid}/export")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Export(Guid id, bool includeChildren = false)
{
IDictionaryItem? dictionaryItem = await _dictionaryItemService.GetAsync(id);
if (dictionaryItem is null)
{
return DictionaryNotFound();
}
XElement xml = _entityXmlSerializer.Serialize(dictionaryItem, includeChildren);
return File(Encoding.UTF8.GetBytes(xml.ToDataString()), MediaTypeNames.Application.Octet, $"{dictionaryItem.ItemKey}.udt");
}
}
@@ -0,0 +1,63 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.Builders;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Api.Management.Services;
using Umbraco.Cms.Api.Management.Services.OperationStatus;
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Security;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
[ApiVersion("1.0")]
public class ImportDictionaryController : DictionaryControllerBase
{
private readonly IDictionaryItemImportService _dictionaryItemImportService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public ImportDictionaryController(
IDictionaryItemImportService dictionaryItemImportService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_dictionaryItemImportService = dictionaryItemImportService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPost("import")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Import(ImportDictionaryRequestModel importDictionaryRequestModel)
{
Attempt<IDictionaryItem?, DictionaryImportOperationStatus> result = await _dictionaryItemImportService
.ImportDictionaryItemFromUdtFileAsync(
importDictionaryRequestModel.TemporaryFile.Id,
importDictionaryRequestModel.Parent?.Id,
CurrentUserKey(_backOfficeSecurityAccessor));
return result.Status switch
{
DictionaryImportOperationStatus.Success => CreatedAtId<ByKeyDictionaryController>(controller => nameof(controller.ByKey), result.Result!.Key),
DictionaryImportOperationStatus.ParentNotFound => NotFound(new ProblemDetailsBuilder()
.WithTitle("The parent dictionary item could not be found.")
.Build()),
DictionaryImportOperationStatus.TemporaryFileNotFound => NotFound(new ProblemDetailsBuilder()
.WithTitle("The temporary file with specified id could not be found.")
.Build()),
DictionaryImportOperationStatus.InvalidFileType => BadRequest(new ProblemDetailsBuilder()
.WithTitle("Invalid file type")
.WithDetail("The dictionary import only supports UDT files.")
.Build()),
DictionaryImportOperationStatus.InvalidFileContent => BadRequest(new ProblemDetailsBuilder()
.WithTitle("Invalid file content")
.WithDetail("The uploaded file could not be read as a valid UDT file.")
.Build()),
_ => StatusCode(StatusCodes.Status500InternalServerError, new ProblemDetailsBuilder()
.WithTitle("Unknown dictionary import operation status.")
.Build()),
};
}
}
@@ -0,0 +1,15 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Core;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Item;
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/dictionary")]
[ApiExplorerSettings(GroupName = "Dictionary")]
[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDictionary)]
public class DictionaryItemControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,33 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.Dictionary.Item;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Item;
[ApiVersion("1.0")]
public class ItemDictionaryItemController : DictionaryItemControllerBase
{
private readonly IDictionaryItemService _dictionaryItemService;
private readonly IUmbracoMapper _mapper;
public ItemDictionaryItemController(IDictionaryItemService dictionaryItemService, IUmbracoMapper mapper)
{
_dictionaryItemService = dictionaryItemService;
_mapper = mapper;
}
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<DictionaryItemItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Item([FromQuery(Name = "id")] HashSet<Guid> ids)
{
IEnumerable<IDictionaryItem> dictionaryItems = await _dictionaryItemService.GetManyAsync(ids.ToArray());
List<DictionaryItemItemResponseModel> responseModels = _mapper.MapEnumerable<IDictionaryItem, DictionaryItemItemResponseModel>(dictionaryItems);
return Ok(responseModels);
}
}
@@ -0,0 +1,47 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
[ApiVersion("1.0")]
public class MoveDictionaryController : DictionaryControllerBase
{
private readonly IDictionaryItemService _dictionaryItemService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public MoveDictionaryController(IDictionaryItemService dictionaryItemService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_dictionaryItemService = dictionaryItemService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPut("{id:guid}/move")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Move(Guid id, MoveDictionaryRequestModel moveDictionaryRequestModel)
{
IDictionaryItem? source = await _dictionaryItemService.GetAsync(id);
if (source == null)
{
return DictionaryNotFound();
}
Attempt<IDictionaryItem, DictionaryItemOperationStatus> result = await _dictionaryItemService.MoveAsync(
source,
moveDictionaryRequestModel.Target?.Id,
CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: DictionaryItemOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,34 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.Services.Paging;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels.Tree;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
[ApiVersion("1.0")]
public class ChildrenDictionaryTreeController : DictionaryTreeControllerBase
{
public ChildrenDictionaryTreeController(IEntityService entityService, IDictionaryItemService dictionaryItemService)
: base(entityService, dictionaryItemService)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<NamedEntityTreeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<NamedEntityTreeItemResponseModel>>> Children(Guid parentId, int skip = 0, int take = 100)
{
if (PaginationService.ConvertSkipTakeToPaging(skip, take, out var pageNumber, out var pageSize, out ProblemDetails? error) == false)
{
return BadRequest(error);
}
PagedModel<IDictionaryItem> paginatedItems = await DictionaryItemService.GetPagedAsync(parentId, skip, take);
return Ok(PagedViewModel(await MapTreeItemViewModels(parentId, paginatedItems.Items), paginatedItems.Total));
}
}
@@ -0,0 +1,53 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.Controllers.Tree;
using Umbraco.Cms.Api.Management.ViewModels.Tree;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Api.Management.ViewModels;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/dictionary")]
[ApiExplorerSettings(GroupName = "Dictionary")]
[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDictionaryOrTemplates)]
// NOTE: at the moment dictionary items (renamed to dictionary tree) aren't supported by EntityService, so we have little use of the
// tree controller base. We'll keep it though, in the hope that we can mend EntityService.
public class DictionaryTreeControllerBase : NamedEntityTreeControllerBase<NamedEntityTreeItemResponseModel>
{
public DictionaryTreeControllerBase(IEntityService entityService, IDictionaryItemService dictionaryItemService)
: base(entityService) =>
DictionaryItemService = dictionaryItemService;
// dictionary items do not currently have a known UmbracoObjectType, so we'll settle with Unknown for now
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.Unknown;
protected IDictionaryItemService DictionaryItemService { get; }
protected async Task<IEnumerable<NamedEntityTreeItemResponseModel>> MapTreeItemViewModels(Guid? parentKey, IEnumerable<IDictionaryItem> dictionaryItems)
{
async Task<NamedEntityTreeItemResponseModel> CreateEntityTreeItemViewModelAsync(IDictionaryItem dictionaryItem)
{
var hasChildren = await DictionaryItemService.CountChildrenAsync(dictionaryItem.Key) > 0;
return new NamedEntityTreeItemResponseModel
{
Name = dictionaryItem.ItemKey,
Id = dictionaryItem.Key,
Type = Constants.UdiEntityType.DictionaryItem,
HasChildren = hasChildren,
Parent = parentKey.HasValue
? new ReferenceByIdModel
{
Id = parentKey.Value
}
: null
};
}
return await Task.WhenAll(dictionaryItems.Select(CreateEntityTreeItemViewModelAsync));
}
}
@@ -0,0 +1,34 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.Services.Paging;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels.Tree;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
[ApiVersion("1.0")]
public class RootDictionaryTreeController : DictionaryTreeControllerBase
{
public RootDictionaryTreeController(IEntityService entityService, IDictionaryItemService dictionaryItemService)
: base(entityService, dictionaryItemService)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<NamedEntityTreeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<NamedEntityTreeItemResponseModel>>> Root(int skip = 0, int take = 100)
{
if (PaginationService.ConvertSkipTakeToPaging(skip, take, out var pageNumber, out var pageSize, out ProblemDetails? error) == false)
{
return BadRequest(error);
}
PagedModel<IDictionaryItem> paginatedItems = await DictionaryItemService.GetPagedAsync(null, skip, take);
return Ok(PagedViewModel(await MapTreeItemViewModels(null, paginatedItems.Items), paginatedItems.Total));
}
}
@@ -0,0 +1,70 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.Security.Authorization.Dictionary;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Dictionary;
[ApiVersion("1.0")]
public class UpdateDictionaryController : DictionaryControllerBase
{
private readonly IDictionaryItemService _dictionaryItemService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
private readonly IDictionaryPresentationFactory _dictionaryPresentationFactory;
private readonly IAuthorizationService _authorizationService;
public UpdateDictionaryController(
IDictionaryItemService dictionaryItemService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
IDictionaryPresentationFactory dictionaryPresentationFactory,
IAuthorizationService authorizationService)
{
_dictionaryItemService = dictionaryItemService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
_dictionaryPresentationFactory = dictionaryPresentationFactory;
_authorizationService = authorizationService;
}
[HttpPut($"{{{nameof(id)}:guid}}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Update(Guid id, UpdateDictionaryItemRequestModel updateDictionaryItemRequestModel)
{
IDictionaryItem? current = await _dictionaryItemService.GetAsync(id);
if (current == null)
{
return DictionaryNotFound();
}
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
new DictionaryPermissionResource(updateDictionaryItemRequestModel.Translations.Select(t => t.IsoCode)),
AuthorizationPolicies.DictionaryPermissionByResource);
if (authorizationResult.Succeeded is false)
{
return Forbidden();
}
IDictionaryItem updated = await _dictionaryPresentationFactory.MapUpdateModelToDictionaryItemAsync(current, updateDictionaryItemRequestModel);
Attempt<IDictionaryItem, DictionaryItemOperationStatus> result =
await _dictionaryItemService.UpdateAsync(updated, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: DictionaryItemOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,58 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class ByKeyDocumentController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentEditingService _contentEditingService;
private readonly IDocumentPresentationFactory _documentPresentationFactory;
public ByKeyDocumentController(
IAuthorizationService authorizationService,
IContentEditingService contentEditingService,
IDocumentPresentationFactory documentPresentationFactory)
{
_authorizationService = authorizationService;
_contentEditingService = contentEditingService;
_documentPresentationFactory = documentPresentationFactory;
}
[HttpGet("{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(DocumentResponseModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> ByKey(Guid id)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionBrowse.ActionLetter, id),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
IContent? content = await _contentEditingService.GetAsync(id);
if (content == null)
{
return DocumentNotFound();
}
DocumentResponseModel model = await _documentPresentationFactory.CreateResponseModelAsync(content);
return Ok(model);
}
}
@@ -0,0 +1,36 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core.Configuration.Models;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class ConfigurationDocumentController : DocumentControllerBase
{
private readonly GlobalSettings _globalSettings;
private readonly ContentSettings _contentSettings;
public ConfigurationDocumentController(IOptionsSnapshot<GlobalSettings> globalSettings, IOptionsSnapshot<ContentSettings> contentSettings)
{
_contentSettings = contentSettings.Value;
_globalSettings = globalSettings.Value;
}
[HttpGet("configuration")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(DocumentConfigurationResponseModel), StatusCodes.Status200OK)]
public Task<IActionResult> Configuration()
{
var responseModel = new DocumentConfigurationResponseModel
{
DisableDeleteWhenReferenced = _contentSettings.DisableDeleteWhenReferenced,
DisableUnpublishWhenReferenced = _contentSettings.DisableUnpublishWhenReferenced,
SanitizeTinyMce = _globalSettings.SanitizeTinyMce,
AllowEditInvariantFromNonDefault = _contentSettings.AllowEditInvariantFromNonDefault,
};
return Task.FromResult<IActionResult>(Ok(responseModel));
}
}
@@ -0,0 +1,62 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class CopyDocumentController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentEditingService _contentEditingService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public CopyDocumentController(
IAuthorizationService authorizationService,
IContentEditingService contentEditingService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_authorizationService = authorizationService;
_contentEditingService = contentEditingService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPost("{id:guid}/copy")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Copy(Guid id, CopyDocumentRequestModel copyDocumentRequestModel)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionCopy.ActionLetter, new[] { copyDocumentRequestModel.Target?.Id, id }),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
Attempt<IContent?, ContentEditingOperationStatus> result = await _contentEditingService.CopyAsync(
id,
copyDocumentRequestModel.Target?.Id,
copyDocumentRequestModel.RelateToOriginal,
copyDocumentRequestModel.IncludeDescendants,
CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? CreatedAtId<ByKeyDocumentController>(controller => nameof(controller.ByKey), result.Result!.Key)
: ContentEditingOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,50 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class CreateDocumentController : CreateDocumentControllerBase
{
private readonly IDocumentEditingPresentationFactory _documentEditingPresentationFactory;
private readonly IContentEditingService _contentEditingService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public CreateDocumentController(
IAuthorizationService authorizationService,
IDocumentEditingPresentationFactory documentEditingPresentationFactory,
IContentEditingService contentEditingService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
: base(authorizationService)
{
_documentEditingPresentationFactory = documentEditingPresentationFactory;
_contentEditingService = contentEditingService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPost]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Create(CreateDocumentRequestModel requestModel)
=> await HandleRequest(requestModel, async () =>
{
ContentCreateModel model = _documentEditingPresentationFactory.MapCreateModel(requestModel);
Attempt<ContentCreateResult, ContentEditingOperationStatus> result =
await _contentEditingService.CreateAsync(model, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? CreatedAtId<ByKeyDocumentController>(controller => nameof(controller.ByKey), result.Result.Content!.Key)
: ContentEditingOperationStatusResult(result.Status);
});
}
@@ -0,0 +1,35 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
public abstract class CreateDocumentControllerBase : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
protected CreateDocumentControllerBase(IAuthorizationService authorizationService)
=> _authorizationService = authorizationService;
protected async Task<IActionResult> HandleRequest(CreateDocumentRequestModel requestModel, Func<Task<IActionResult>> authorizedHandler)
{
IEnumerable<string> cultures = requestModel.Variants
.Where(v => v.Culture is not null)
.Select(v => v.Culture!);
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionNew.ActionLetter, requestModel.Parent?.Id, cultures),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
return await authorizedHandler();
}
}
@@ -0,0 +1,59 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.ViewModels.PublicAccess;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class CreatePublicAccessDocumentController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IPublicAccessPresentationFactory _publicAccessPresentationFactory;
private readonly IPublicAccessService _publicAccessService;
public CreatePublicAccessDocumentController(
IAuthorizationService authorizationService,
IPublicAccessPresentationFactory publicAccessPresentationFactory,
IPublicAccessService publicAccessService)
{
_authorizationService = authorizationService;
_publicAccessPresentationFactory = publicAccessPresentationFactory;
_publicAccessService = publicAccessService;
}
[MapToApiVersion("1.0")]
[HttpPost("{id:guid}/public-access")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Create(Guid id, PublicAccessRequestModel publicAccessRequestModel)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionProtect.ActionLetter, id),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
PublicAccessEntrySlim publicAccessEntrySlim = _publicAccessPresentationFactory.CreatePublicAccessEntrySlim(publicAccessRequestModel, id);
Attempt<PublicAccessEntry?, PublicAccessOperationStatus> saveAttempt = await _publicAccessService.CreateAsync(publicAccessEntrySlim);
return saveAttempt.Success
? CreatedAtId<GetPublicAccessDocumentController>(controller => nameof(controller.GetPublicAccess), saveAttempt.Result!.Key)
: PublicAccessOperationStatusResult(saveAttempt.Status);
}
}
@@ -0,0 +1,57 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class DeleteDocumentController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentEditingService _contentEditingService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public DeleteDocumentController(
IAuthorizationService authorizationService,
IContentEditingService contentEditingService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_authorizationService = authorizationService;
_contentEditingService = contentEditingService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpDelete("{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Delete(Guid id)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionDelete.ActionLetter, id),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
Attempt<IContent?, ContentEditingOperationStatus> result = await _contentEditingService.DeleteAsync(id, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: ContentEditingOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,47 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class DeletePublicAccessDocumentController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IPublicAccessService _publicAccessService;
public DeletePublicAccessDocumentController(IAuthorizationService authorizationService, IPublicAccessService publicAccessService)
{
_authorizationService = authorizationService;
_publicAccessService = publicAccessService;
}
[MapToApiVersion("1.0")]
[HttpDelete("{id:guid}/public-access")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Delete(Guid id)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionProtect.ActionLetter, id),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
Attempt<PublicAccessOperationStatus> attempt = await _publicAccessService.DeleteAsync(id);
return attempt.Success ? Ok() : PublicAccessOperationStatusResult(attempt.Result);
}
}
@@ -0,0 +1,144 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Controllers.Content;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Api.Management.ViewModels.Content;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Models.ContentPublishing;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiController]
[VersionedApiBackOfficeRoute(Constants.UdiEntityType.Document)]
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))]
[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocuments)]
public abstract class DocumentControllerBase : ContentControllerBase
{
protected IActionResult DocumentNotFound()
=> OperationStatusResult(ContentEditingOperationStatus.NotFound, problemDetailsBuilder
=> NotFound(problemDetailsBuilder
.WithTitle("The document could not be found")
.Build()));
protected IActionResult DocumentEditingOperationStatusResult<TContentModelBase>(
ContentEditingOperationStatus status,
TContentModelBase requestModel,
ContentValidationResult validationResult)
where TContentModelBase : ContentModelBase<DocumentValueModel, DocumentVariantRequestModel>
=> ContentEditingOperationStatusResult<TContentModelBase, DocumentValueModel, DocumentVariantRequestModel>(status, requestModel, validationResult);
protected IActionResult DocumentPublishingOperationStatusResult(
ContentPublishingOperationStatus status,
IEnumerable<string>? invalidPropertyAliases = null,
IEnumerable<ContentPublishingBranchItemResult>? failedBranchItems = null)
=> OperationStatusResult(status, problemDetailsBuilder => status switch
{
ContentPublishingOperationStatus.ContentNotFound => NotFound(problemDetailsBuilder
.WithTitle("The requested document could not be found")
.Build()),
ContentPublishingOperationStatus.CancelledByEvent => BadRequest(problemDetailsBuilder
.WithTitle("Publish cancelled by event")
.WithDetail("The publish operation was cancelled by an event.")
.Build()),
ContentPublishingOperationStatus.ContentInvalid => BadRequest(problemDetailsBuilder
.WithTitle("Invalid document")
.WithDetail("The specified document had an invalid configuration.")
.WithExtension("invalidProperties", invalidPropertyAliases ?? Enumerable.Empty<string>())
.Build()),
ContentPublishingOperationStatus.NothingToPublish => BadRequest(problemDetailsBuilder
.WithTitle("Nothing to publish")
.WithDetail("None of the specified cultures needed publishing.")
.Build()),
ContentPublishingOperationStatus.MandatoryCultureMissing => BadRequest(problemDetailsBuilder
.WithTitle("Mandatory culture missing")
.WithDetail("Must include all mandatory cultures when publishing.")
.Build()),
ContentPublishingOperationStatus.HasExpired => BadRequest(problemDetailsBuilder
.WithTitle("Document expired")
.WithDetail("Could not publish the document because it was expired.")
.Build()),
ContentPublishingOperationStatus.CultureHasExpired => BadRequest(problemDetailsBuilder
.WithTitle("Document culture expired")
.WithDetail("Could not publish the document because some of the specified cultures were expired.")
.Build()),
ContentPublishingOperationStatus.AwaitingRelease => BadRequest(problemDetailsBuilder
.WithTitle("Document awaiting release")
.WithDetail("Could not publish the document because it was awaiting release.")
.Build()),
ContentPublishingOperationStatus.CultureAwaitingRelease => BadRequest(problemDetailsBuilder
.WithTitle("Document culture awaiting release")
.WithDetail(
"Could not publish the document because some of the specified cultures were awaiting release.")
.Build()),
ContentPublishingOperationStatus.InTrash => BadRequest(problemDetailsBuilder
.WithTitle("Document in the recycle bin")
.WithDetail("Could not publish the document because it was in the recycle bin.")
.Build()),
ContentPublishingOperationStatus.PathNotPublished => BadRequest(problemDetailsBuilder
.WithTitle("Parent not published")
.WithDetail("Could not publish the document because its parent was not published.")
.Build()),
ContentPublishingOperationStatus.ConcurrencyViolation => BadRequest(problemDetailsBuilder
.WithTitle("Concurrency violation detected")
.WithDetail("An attempt was made to publish a version older than the latest version.")
.Build()),
ContentPublishingOperationStatus.UnsavedChanges => BadRequest(problemDetailsBuilder
.WithTitle("Unsaved changes")
.WithDetail(
"Could not publish the document because it had unsaved changes. Make sure to save all changes before attempting a publish.")
.Build()),
ContentPublishingOperationStatus.FailedBranch => BadRequest(problemDetailsBuilder
.WithTitle("Failed branch operation")
.WithDetail("One or more items in the branch could not complete the operation.")
.WithExtension("failedBranchItems", failedBranchItems?.Select(item => new DocumentPublishBranchItemResult
{
Id = item.Key,
OperationStatus = item.OperationStatus
}) ?? Enumerable.Empty<DocumentPublishBranchItemResult>())
.Build()),
ContentPublishingOperationStatus.Failed => BadRequest(problemDetailsBuilder
.WithTitle("Publish or unpublish failed")
.WithDetail(
"An unspecified error occurred while (un)publishing. Please check the logs for additional information.")
.Build()),
_ => StatusCode(StatusCodes.Status500InternalServerError, "Unknown content operation status."),
});
protected IActionResult PublicAccessOperationStatusResult(PublicAccessOperationStatus status)
=> OperationStatusResult(status, problemDetailsBuilder => status switch
{
PublicAccessOperationStatus.ContentNotFound => NotFound(problemDetailsBuilder
.WithTitle("The document could not be found")
.Build()),
PublicAccessOperationStatus.ErrorNodeNotFound => NotFound(problemDetailsBuilder
.WithTitle("The error page could not be found")
.Build()),
PublicAccessOperationStatus.LoginNodeNotFound => NotFound(problemDetailsBuilder
.WithTitle("The login page could not be found")
.Build()),
PublicAccessOperationStatus.NoAllowedEntities => BadRequest(problemDetailsBuilder
.WithTitle("No allowed entities given")
.WithDetail("Both MemberGroups and Members were empty, thus no entities can be allowed.")
.Build()),
PublicAccessOperationStatus.CancelledByNotification => BadRequest(problemDetailsBuilder
.WithTitle("Request cancelled by notification")
.WithDetail("The request to save a public access entry was cancelled by a notification handler.")
.Build()),
PublicAccessOperationStatus.AmbiguousRule => BadRequest(problemDetailsBuilder
.WithTitle("Ambiguous Rule")
.WithDetail("The specified rule is ambiguous, because both member groups and member names were given.")
.Build()),
PublicAccessOperationStatus.EntryNotFound => BadRequest(problemDetailsBuilder
.WithTitle("Entry not found")
.WithDetail("The specified entry was not found.")
.Build()),
_ => StatusCode(StatusCodes.Status500InternalServerError, problemDetailsBuilder
.WithTitle("Unknown content operation status.")
.Build()),
});
}
@@ -0,0 +1,36 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class DomainsController : DocumentControllerBase
{
private readonly IDomainService _domainService;
private readonly IUmbracoMapper _umbracoMapper;
public DomainsController(IDomainService domainService, IUmbracoMapper umbracoMapper)
{
_domainService = domainService;
_umbracoMapper = umbracoMapper;
}
[MapToApiVersion("1.0")]
[HttpGet("{id:guid}/domains")]
[ProducesResponseType(typeof(DomainsResponseModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Domains(Guid id)
{
IDomain[] assignedDomains = (await _domainService.GetAssignedDomainsAsync(id, true))
.OrderBy(d => d.SortOrder)
.ToArray();
DomainsResponseModel responseModel = _umbracoMapper.Map<DomainsResponseModel>(assignedDomains)!;
return Ok(responseModel);
}
}
@@ -0,0 +1,73 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.ViewModels.PublicAccess;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class GetPublicAccessDocumentController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IPublicAccessService _publicAccessService;
private readonly IPublicAccessPresentationFactory _publicAccessPresentationFactory;
public GetPublicAccessDocumentController(
IAuthorizationService authorizationService,
IPublicAccessService publicAccessService,
IPublicAccessPresentationFactory publicAccessPresentationFactory)
{
_authorizationService = authorizationService;
_publicAccessService = publicAccessService;
_publicAccessPresentationFactory = publicAccessPresentationFactory;
}
[MapToApiVersion("1.0")]
[HttpGet("{id:guid}/public-access")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetPublicAccess(Guid id)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionProtect.ActionLetter, id),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
Attempt<PublicAccessEntry?, PublicAccessOperationStatus> accessAttempt =
await _publicAccessService.GetEntryByContentKeyAsync(id);
if (accessAttempt.Success is false)
{
return PublicAccessOperationStatusResult(accessAttempt.Status);
}
if (accessAttempt.Result is null)
{
return Ok();
}
Attempt<PublicAccessResponseModel?, PublicAccessOperationStatus> responseModelAttempt =
_publicAccessPresentationFactory.CreatePublicAccessResponseModel(accessAttempt.Result);
if (responseModelAttempt.Success is false)
{
return PublicAccessOperationStatusResult(responseModelAttempt.Status);
}
return Ok(responseModelAttempt.Result);
}
}
@@ -0,0 +1,15 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Core;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.Document.Item;
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.Document}")]
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))]
[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocuments)]
public class DocumentItemControllerBase : ManagementApiControllerBase
{
}
@@ -0,0 +1,36 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Document.Item;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Document.Item;
[ApiVersion("1.0")]
public class ItemDocumentItemController : DocumentItemControllerBase
{
private readonly IEntityService _entityService;
private readonly IDocumentPresentationFactory _documentPresentationFactory;
public ItemDocumentItemController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
{
_entityService = entityService;
_documentPresentationFactory = documentPresentationFactory;
}
[HttpGet]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(IEnumerable<DocumentItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Item([FromQuery(Name = "id")] HashSet<Guid> ids)
{
IEnumerable<IDocumentEntitySlim> documents = _entityService
.GetAll(UmbracoObjectTypes.Document, ids.ToArray())
.OfType<IDocumentEntitySlim>();
IEnumerable<DocumentItemResponseModel> documentItemResponseModels = documents.Select(_documentPresentationFactory.CreateItemResponseModel);
return await Task.FromResult(Ok(documentItemResponseModels));
}
}
@@ -0,0 +1,60 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class MoveDocumentController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentEditingService _contentEditingService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public MoveDocumentController(
IAuthorizationService authorizationService,
IContentEditingService contentEditingService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_authorizationService = authorizationService;
_contentEditingService = contentEditingService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPut("{id:guid}/move")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Move(Guid id, MoveDocumentRequestModel moveDocumentRequestModel)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionMove.ActionLetter, new[] { moveDocumentRequestModel.Target?.Id, id }),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
Attempt<IContent?, ContentEditingOperationStatus> result = await _contentEditingService.MoveAsync(
id,
moveDocumentRequestModel.Target?.Id,
CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: ContentEditingOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,56 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class MoveToRecycleBinDocumentController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentEditingService _contentEditingService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public MoveToRecycleBinDocumentController(
IAuthorizationService authorizationService,
IContentEditingService contentEditingService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_authorizationService = authorizationService;
_contentEditingService = contentEditingService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPut("{id:guid}/move-to-recycle-bin")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> MoveToRecycleBin(Guid id)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionDelete.ActionLetter, id),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
Attempt<IContent?, ContentEditingOperationStatus> result = await _contentEditingService.MoveToRecycleBinAsync(id, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: ContentEditingOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,54 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class NotificationsController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentEditingService _contentEditingService;
private readonly IDocumentNotificationPresentationFactory _documentNotificationPresentationFactory;
public NotificationsController(
IAuthorizationService authorizationService,
IContentEditingService contentEditingService,
IDocumentNotificationPresentationFactory documentNotificationPresentationFactory)
{
_authorizationService = authorizationService;
_contentEditingService = contentEditingService;
_documentNotificationPresentationFactory = documentNotificationPresentationFactory;
}
[MapToApiVersion("1.0")]
[HttpGet("{id:guid}/notifications")]
[ProducesResponseType(typeof(IEnumerable<DocumentNotificationResponseModel>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Notifications(Guid id)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionBrowse.ActionLetter, id),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
IContent? content = await _contentEditingService.GetAsync(id);
return content != null
? Ok(await _documentNotificationPresentationFactory.CreateNotificationModelsAsync(content))
: DocumentNotFound();
}
}
@@ -0,0 +1,61 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.Security.Authorization.UserGroup;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models.ContentPublishing;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class PublishDocumentController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentPublishingService _contentPublishingService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public PublishDocumentController(
IAuthorizationService authorizationService,
IContentPublishingService contentPublishingService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_authorizationService = authorizationService;
_contentPublishingService = contentPublishingService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPut("{id:guid}/publish")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Publish(Guid id, PublishDocumentRequestModel requestModel)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionPublish.ActionLetter, id, requestModel.Cultures),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
Attempt<ContentPublishingResult, ContentPublishingOperationStatus> attempt = await _contentPublishingService.PublishAsync(
id,
requestModel.Cultures,
CurrentUserKey(_backOfficeSecurityAccessor));
return attempt.Success
? Ok()
: DocumentPublishingOperationStatusResult(attempt.Status, invalidPropertyAliases: attempt.Result.InvalidPropertyAliases);
}
}
@@ -0,0 +1,62 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models.ContentPublishing;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class PublishDocumentWithDescendantsController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentPublishingService _contentPublishingService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public PublishDocumentWithDescendantsController(
IAuthorizationService authorizationService,
IContentPublishingService contentPublishingService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_authorizationService = authorizationService;
_contentPublishingService = contentPublishingService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPut("{id:guid}/publish-with-descendants")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> PublishWithDescendants(Guid id, PublishDocumentWithDescendantsRequestModel requestModel)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.Branch(ActionPublish.ActionLetter, id, requestModel.Cultures),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
Attempt<ContentPublishingBranchResult, ContentPublishingOperationStatus> attempt = await _contentPublishingService.PublishBranchAsync(
id,
requestModel.Cultures,
requestModel.IncludeUnpublishedDescendants,
CurrentUserKey(_backOfficeSecurityAccessor));
return attempt.Success
? Ok()
: DocumentPublishingOperationStatusResult(attempt.Status, failedBranchItems: attempt.Result.FailedItems);
}
}
@@ -0,0 +1,24 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Document.RecycleBin;
namespace Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
[ApiVersion("1.0")]
public class ChildrenDocumentRecycleBinController : DocumentRecycleBinControllerBase
{
public ChildrenDocumentRecycleBinController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
: base(entityService, documentPresentationFactory)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DocumentRecycleBinItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DocumentRecycleBinItemResponseModel>>> Children(Guid parentId, int skip = 0, int take = 100)
=> await GetChildren(parentId, skip, take);
}
@@ -0,0 +1,61 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
[ApiVersion("1.0")]
public class DeleteDocumentRecycleBinController : DocumentRecycleBinControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
private readonly IContentEditingService _contentEditingService;
public DeleteDocumentRecycleBinController(
IEntityService entityService,
IDocumentPresentationFactory documentPresentationFactory,
IAuthorizationService authorizationService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
IContentEditingService contentEditingService)
: base(entityService, documentPresentationFactory)
{
_authorizationService = authorizationService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
_contentEditingService = contentEditingService;
}
[HttpDelete("{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Delete(Guid id)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.RecycleBin(ActionDelete.ActionLetter),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
Attempt<IContent?, ContentEditingOperationStatus> result = await _contentEditingService.DeleteFromRecycleBinAsync(id, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: ContentEditingOperationStatusResult(result.Status);
}
}
@@ -0,0 +1,45 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.Controllers.RecycleBin;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.Filters;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Api.Management.ViewModels.Document.RecycleBin;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.RecycleBin}/{Constants.UdiEntityType.Document}")]
[RequireDocumentTreeRootAccess]
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))]
[Authorize(Policy = "New" + AuthorizationPolicies.TreeAccessDocuments)]
public class DocumentRecycleBinControllerBase : RecycleBinControllerBase<DocumentRecycleBinItemResponseModel>
{
private readonly IDocumentPresentationFactory _documentPresentationFactory;
public DocumentRecycleBinControllerBase(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
: base(entityService)
=> _documentPresentationFactory = documentPresentationFactory;
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.Document;
protected override int RecycleBinRootId => Constants.System.RecycleBinContent;
protected override DocumentRecycleBinItemResponseModel MapRecycleBinViewModel(Guid? parentId, IEntitySlim entity)
{
DocumentRecycleBinItemResponseModel responseModel = base.MapRecycleBinViewModel(parentId, entity);
if (entity is IDocumentEntitySlim documentEntitySlim)
{
responseModel.Variants = _documentPresentationFactory.CreateVariantsItemResponseModels(documentEntitySlim);
responseModel.DocumentType = _documentPresentationFactory.CreateDocumentTypeReferenceResponseModel(documentEntitySlim);
}
return responseModel;
}
}
@@ -0,0 +1,56 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
[ApiVersion("1.0")]
public class EmptyDocumentRecycleBinController : DocumentRecycleBinControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
private readonly IContentService _contentService;
public EmptyDocumentRecycleBinController(
IEntityService entityService,
IAuthorizationService authorizationService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
IContentService contentService,
IDocumentPresentationFactory documentPresentationFactory)
: base(entityService, documentPresentationFactory)
{
_authorizationService = authorizationService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
_contentService = contentService;
}
[HttpDelete]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> EmptyRecycleBin()
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.RecycleBin(ActionDelete.ActionLetter),
AuthorizationPolicies.ContentPermissionByResource);
if (authorizationResult.Succeeded is false)
{
return Forbidden();
}
OperationResult result = await _contentService.EmptyRecycleBinAsync(CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: OperationStatusResult(result);
}
}
@@ -0,0 +1,24 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Document.RecycleBin;
namespace Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
[ApiVersion("1.0")]
public class RootDocumentRecycleBinController : DocumentRecycleBinControllerBase
{
public RootDocumentRecycleBinController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
: base(entityService, documentPresentationFactory)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DocumentRecycleBinItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DocumentRecycleBinItemResponseModel>>> Root(int skip = 0, int take = 100)
=> await GetRoot(skip, take);
}
@@ -0,0 +1,60 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.ViewModels.Sorting;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class SortDocumentController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentEditingService _contentEditingService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public SortDocumentController(
IAuthorizationService authorizationService,
IContentEditingService contentEditingService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_authorizationService = authorizationService;
_contentEditingService = contentEditingService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPut("sort")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Sort(SortingRequestModel sortingRequestModel)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionSort.ActionLetter, new List<Guid?>(sortingRequestModel.Sorting.Select(x => x.Id).Cast<Guid?>()) { sortingRequestModel.Parent?.Id }),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
ContentEditingOperationStatus result = await _contentEditingService.SortAsync(
sortingRequestModel.Parent?.Id,
sortingRequestModel.Sorting.Select(m => new SortingModel { Key = m.Id, SortOrder = m.SortOrder }),
CurrentUserKey(_backOfficeSecurityAccessor));
return result == ContentEditingOperationStatus.Success
? Ok()
: ContentEditingOperationStatusResult(result);
}
}
@@ -0,0 +1,44 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.Services.Entities;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Tree;
namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree;
[ApiVersion("1.0")]
public class ChildrenDocumentTreeController : DocumentTreeControllerBase
{
public ChildrenDocumentTreeController(
IEntityService entityService,
IUserStartNodeEntitiesService userStartNodeEntitiesService,
IDataTypeService dataTypeService,
IPublicAccessService publicAccessService,
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
IDocumentPresentationFactory documentPresentationFactory)
: base(
entityService,
userStartNodeEntitiesService,
dataTypeService,
publicAccessService,
appCaches,
backofficeSecurityAccessor,
documentPresentationFactory)
{
}
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DocumentTreeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DocumentTreeItemResponseModel>>> Children(Guid parentId, int skip = 0, int take = 100, Guid? dataTypeId = null)
{
IgnoreUserStartNodesForDataType(dataTypeId);
return await GetChildren(parentId, skip, take);
}
}
@@ -0,0 +1,85 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.Controllers.Tree;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.Services.Entities;
using Umbraco.Cms.Api.Management.ViewModels.Tree;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree;
[ApiController]
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.Document}")]
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Document))]
[Authorize(Policy = "New" + AuthorizationPolicies.SectionAccessForContentTree)]
public abstract class DocumentTreeControllerBase : UserStartNodeTreeControllerBase<DocumentTreeItemResponseModel>
{
private readonly IPublicAccessService _publicAccessService;
private readonly AppCaches _appCaches;
private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor;
private readonly IDocumentPresentationFactory _documentPresentationFactory;
protected DocumentTreeControllerBase(
IEntityService entityService,
IUserStartNodeEntitiesService userStartNodeEntitiesService,
IDataTypeService dataTypeService,
IPublicAccessService publicAccessService,
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
IDocumentPresentationFactory documentPresentationFactory)
: base(entityService, userStartNodeEntitiesService, dataTypeService)
{
_publicAccessService = publicAccessService;
_appCaches = appCaches;
_backofficeSecurityAccessor = backofficeSecurityAccessor;
_documentPresentationFactory = documentPresentationFactory;
}
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.Document;
protected override Ordering ItemOrdering => Ordering.By(nameof(Infrastructure.Persistence.Dtos.NodeDto.SortOrder));
protected override DocumentTreeItemResponseModel MapTreeItemViewModel(Guid? parentId, IEntitySlim entity)
{
DocumentTreeItemResponseModel responseModel = base.MapTreeItemViewModel(parentId, entity);
if (entity is IDocumentEntitySlim documentEntitySlim)
{
responseModel.IsProtected = _publicAccessService.IsProtected(entity.Path);
responseModel.IsTrashed = entity.Trashed;
responseModel.Id = entity.Key;
responseModel.Variants = _documentPresentationFactory.CreateVariantsItemResponseModels(documentEntitySlim);
responseModel.DocumentType = _documentPresentationFactory.CreateDocumentTypeReferenceResponseModel(documentEntitySlim);
}
return responseModel;
}
// TODO: delete these (faking start node setup for unlimited editor)
protected override int[] GetUserStartNodeIds() => new[] { -1 };
protected override string[] GetUserStartNodePaths() => Array.Empty<string>();
// TODO: use these implementations instead of the dummy ones above once we have backoffice auth in place
// protected override int[] GetUserStartNodeIds()
// => _backofficeSecurityAccessor
// .BackOfficeSecurity?
// .CurrentUser?
// .CalculateContentStartNodeIds(EntityService, _appCaches)
// ?? Array.Empty<int>();
//
// protected override string[] GetUserStartNodePaths()
// => _backofficeSecurityAccessor
// .BackOfficeSecurity?
// .CurrentUser?
// .GetContentStartNodePaths(EntityService, _appCaches)
// ?? Array.Empty<string>();
}
@@ -0,0 +1,44 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.Services.Entities;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Tree;
namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree;
[ApiVersion("1.0")]
public class RootDocumentTreeController : DocumentTreeControllerBase
{
public RootDocumentTreeController(
IEntityService entityService,
IUserStartNodeEntitiesService userStartNodeEntitiesService,
IDataTypeService dataTypeService,
IPublicAccessService publicAccessService,
AppCaches appCaches,
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
IDocumentPresentationFactory documentPresentationFactory)
: base(
entityService,
userStartNodeEntitiesService,
dataTypeService,
publicAccessService,
appCaches,
backofficeSecurityAccessor,
documentPresentationFactory)
{
}
[HttpGet("root")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DocumentTreeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DocumentTreeItemResponseModel>>> Root(int skip = 0, int take = 100, Guid? dataTypeId = null)
{
IgnoreUserStartNodesForDataType(dataTypeId);
return await GetRoot(skip, take);
}
}
@@ -0,0 +1,63 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class UnpublishDocumentController : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentPublishingService _contentPublishingService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public UnpublishDocumentController(
IAuthorizationService authorizationService,
IContentPublishingService contentPublishingService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_authorizationService = authorizationService;
_contentPublishingService = contentPublishingService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPut("{id:guid}/unpublish")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Unpublish(Guid id, UnpublishDocumentRequestModel requestModel)
{
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(
ActionUnpublish.ActionLetter,
id,
requestModel.Culture is not null ? requestModel.Culture.Yield() : Enumerable.Empty<string>()),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
Attempt<ContentPublishingOperationStatus> attempt = await _contentPublishingService.UnpublishAsync(
id,
requestModel.Culture,
CurrentUserKey(_backOfficeSecurityAccessor));
return attempt.Success
? Ok()
: DocumentPublishingOperationStatusResult(attempt.Result);
}
}
@@ -0,0 +1,50 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class UpdateDocumentController : UpdateDocumentControllerBase
{
private readonly IContentEditingService _contentEditingService;
private readonly IDocumentEditingPresentationFactory _documentEditingPresentationFactory;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public UpdateDocumentController(
IAuthorizationService authorizationService,
IContentEditingService contentEditingService,
IDocumentEditingPresentationFactory documentEditingPresentationFactory,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
: base(authorizationService, contentEditingService)
{
_contentEditingService = contentEditingService;
_documentEditingPresentationFactory = documentEditingPresentationFactory;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[HttpPut("{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Update(Guid id, UpdateDocumentRequestModel requestModel)
=> await HandleRequest(id, requestModel, async content =>
{
ContentUpdateModel model = _documentEditingPresentationFactory.MapUpdateModel(requestModel);
Attempt<ContentUpdateResult, ContentEditingOperationStatus> result =
await _contentEditingService.UpdateAsync(content, model, CurrentUserKey(_backOfficeSecurityAccessor));
return result.Success
? Ok()
: ContentEditingOperationStatusResult(result.Status);
});
}
@@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
public abstract class UpdateDocumentControllerBase : DocumentControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IContentEditingService _contentEditingService;
protected UpdateDocumentControllerBase(IAuthorizationService authorizationService, IContentEditingService contentEditingService)
{
_authorizationService = authorizationService;
_contentEditingService = contentEditingService;
}
protected async Task<IActionResult> HandleRequest(Guid id, UpdateDocumentRequestModel requestModel, Func<IContent, Task<IActionResult>> authorizedHandler)
{
IEnumerable<string> cultures = requestModel.Variants
.Where(v => v.Culture is not null)
.Select(v => v.Culture!);
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
User,
ContentPermissionResource.WithKeys(ActionUpdate.ActionLetter, id, cultures),
AuthorizationPolicies.ContentPermissionByResource);
if (!authorizationResult.Succeeded)
{
return Forbidden();
}
IContent? content = await _contentEditingService.GetAsync(id);
if (content is null)
{
return DocumentNotFound();
}
return await authorizedHandler(content);
}
}
@@ -0,0 +1,58 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.Builders;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class UpdateDomainsController : DocumentControllerBase
{
private readonly IDomainService _domainService;
private readonly IUmbracoMapper _umbracoMapper;
public UpdateDomainsController(IDomainService domainService, IUmbracoMapper umbracoMapper)
{
_domainService = domainService;
_umbracoMapper = umbracoMapper;
}
[MapToApiVersion("1.0")]
[HttpPut("{id:guid}/domains")]
public async Task<IActionResult> Update(Guid id, UpdateDomainsRequestModel updateModel)
{
DomainsUpdateModel domainsUpdateModel = _umbracoMapper.Map<DomainsUpdateModel>(updateModel)!;
Attempt<IEnumerable<IDomain>, DomainOperationStatus> result = await _domainService.UpdateDomainsAsync(id, domainsUpdateModel);
return result.Status switch
{
DomainOperationStatus.Success => Ok(),
DomainOperationStatus.CancelledByNotification => BadRequest(new ProblemDetailsBuilder()
.WithTitle("Cancelled by notification")
.WithDetail("A notification handler prevented the domain update operation.")
.Build()),
DomainOperationStatus.ContentNotFound => NotFound(new ProblemDetailsBuilder()
.WithTitle("The targeted content item was not found.")
.Build()),
DomainOperationStatus.LanguageNotFound => BadRequest(new ProblemDetailsBuilder()
.WithTitle("Invalid language specified")
.WithDetail("One or more of the specified language ISO codes could not be found.")
.Build()),
DomainOperationStatus.DuplicateDomainName => Conflict(new ProblemDetailsBuilder()
.WithTitle("Duplicate domain name detected")
.WithDetail("One or more of the specified domain names were duplicates, possibly of assignments to other content items.")
.Build()),
_ => StatusCode(StatusCodes.Status500InternalServerError, new ProblemDetailsBuilder()
.WithTitle("Unknown domain update operation status.")
.Build()),
};
}
}
@@ -0,0 +1,40 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.Document;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Document;
[ApiVersion("1.0")]
public class UpdateNotificationsController : DocumentControllerBase
{
private readonly IContentEditingService _contentEditingService;
private readonly INotificationService _notificationService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
public UpdateNotificationsController(IContentEditingService contentEditingService, INotificationService notificationService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_contentEditingService = contentEditingService;
_notificationService = notificationService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}
[MapToApiVersion("1.0")]
[HttpPut("{id:guid}/notifications")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> UpdateNotifications(Guid id, UpdateDocumentNotificationsRequestModel updateModel)
{
IContent? content = await _contentEditingService.GetAsync(id);
if (content == null)
{
return DocumentNotFound();
}
_notificationService.SetNotifications(_backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser, content, updateModel.SubscribedActionIds);
return await Task.FromResult(Ok());
}
}

Some files were not shown because too many files have changed in this diff Show More