Skip to content

Commit fb2aad0

Browse files
authored
V16: Adds a state for "forbidden" for entities that return 403 (Access denied) (#19557)
* feat: adds new localization keys for forbidden routes * feat: ignore all 400, 401, 403, and 404 errors as they are handled by the UI * feat: adds new elements to show forbidden routes and entities * feat: adds generic forbidden state to base entities * feat: injects a forbidden route component to documents * feat: adds 'forbidden' state to media workspace * chore: aligns document and media workspaces * test(mock): adds user configuration endpoint * test(mock): adds calculate-start-nodes endpoint to users * test(mock): adds missing endpoint for 'client-credentials' * feat: clean up old observers on entity errors * feat: aligns UI for better DX if there is no user * fix: returns early if there is no user, instead of trying to append properties to the object * feat: adds 'forbidden' state to members * feat: adds support for forbidden document blueprints * feat: allows parent to be undefined as well as null * feat: forbidden route for members as a state * chore: simplify language workspace * test: adds forbidden mock data * test: adds missing endpoints and a check for forbidden ids
1 parent 861afde commit fb2aad0

File tree

62 files changed

+1193
-115
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1193
-115
lines changed

src/Umbraco.Web.UI.Client/src/assets/lang/da.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,24 @@ export default {
343343
blueprintDescription:
344344
'En indholdskabelon er foruddefineret indhold, som en redaktør kan vælge at bruge\n som grundlag for at oprette nyt indhold\n ',
345345
},
346+
entityDetail: {
347+
notFoundTitle: (entityType: string) => {
348+
const entityName = entityType ?? 'Elementet';
349+
return `${entityName} blev ikke fundet`;
350+
},
351+
notFoundDescription: (entityType: string) => {
352+
const entityName = entityType ?? 'element';
353+
return `Den/det ønskede ${entityName} kunne ikke findes. Dette kan skyldes, at den/det er blevet slettet, eller at du ikke har adgang. Kontakt din administrator for hjælp.`;
354+
},
355+
forbiddenTitle: (entityType: string) => {
356+
const entityName = entityType ?? 'Elementet';
357+
return `${entityName} er ikke tilgængelig`;
358+
},
359+
forbiddenDescription: (entityType: string) => {
360+
const entityName = entityType ?? 'element';
361+
return `Du har ikke adgang til den/det ønskede ${entityName}. Kontakt din administrator for hjælp.`;
362+
},
363+
},
346364
media: {
347365
clickToUpload: 'Klik for at uploade',
348366
orClickHereToUpload: 'eller klik her for at vælge filer',
@@ -2606,6 +2624,9 @@ export default {
26062624
routing: {
26072625
routeNotFoundTitle: 'Ikke fundet',
26082626
routeNotFoundDescription: 'Den side du leder efter kunne ikke findes. Kontroller adressen og prøv igen.',
2627+
routeForbiddenTitle: 'Adgang nægtet',
2628+
routeForbiddenDescription:
2629+
'Du har ikke tilladelse til at få adgang til denne ressource. Kontakt venligst din administrator for hjælp.',
26092630
},
26102631
codeEditor: {
26112632
label: 'Code editor',

src/Umbraco.Web.UI.Client/src/assets/lang/de.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,24 @@ export default {
344344
blueprintDescription:
345345
'Eine Inhaltsvorlage ist vordefinierter Inhalt,\n den ein Redakteur als Basis für neuen Inhalt verwenden kann\n ',
346346
},
347+
entityDetail: {
348+
notFoundTitle: (entityType: string) => {
349+
const entityName = entityType ?? 'Element';
350+
return `${entityName} nicht gefunden`;
351+
},
352+
notFoundDescription: (entityType: string) => {
353+
const entityName = entityType ?? 'element';
354+
return `Der angeforderte ${entityName} konnte nicht gefunden werden. Bitte überprüfen Sie die URL und versuchen Sie es erneut.`;
355+
},
356+
forbiddenTitle: (entityType: string) => {
357+
const entityName = entityType ?? 'Element';
358+
return `${entityName} nicht verfügbar`;
359+
},
360+
forbiddenDescription: (entityType: string) => {
361+
const entityName = entityType ?? 'dieses Element';
362+
return `Sie haben keine Berechtigung, auf ${entityName} zuzugreifen. Bitte wenden Sie sich an Ihren Administrator, um Unterstützung zu erhalten.`;
363+
},
364+
},
347365
media: {
348366
clickToUpload: 'Für Upload klicken',
349367
orClickHereToUpload: 'oder klicken Sie hier um eine Datei zu wählen',
@@ -2007,4 +2025,12 @@ export default {
20072025
searchResult: 'Element zurückgegeben',
20082026
searchResults: 'Elemente zurückgegeben',
20092027
},
2028+
routing: {
2029+
routeNotFoundTitle: 'Seite wurde nicht gefunden',
2030+
routeNotFoundDescription:
2031+
'Die angeforderte Seite konnte nicht gefunden werden. Bitte überprüfen Sie die URL und versuchen Sie es erneut.',
2032+
routeForbiddenTitle: 'Zugriff verweigert',
2033+
routeForbiddenDescription:
2034+
'Sie haben keine Berechtigung, auf diese Seite zuzugreifen. Bitte wenden Sie sich an Ihren Administrator, um Unterstützung zu erhalten.',
2035+
},
20102036
} as UmbLocalizationDictionary;

src/Umbraco.Web.UI.Client/src/assets/lang/en.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,14 @@ export default {
374374
const entityName = entityType ?? 'item';
375375
return `The requested ${entityName} could not be found. Please check the URL and try again.`;
376376
},
377+
forbiddenTitle: (entityType: string) => {
378+
const entityName = entityType ?? 'item';
379+
return `Access denied to this ${entityName}`;
380+
},
381+
forbiddenDescription: (entityType: string) => {
382+
const entityName = entityType ?? 'item';
383+
return `You do not have permission to access this ${entityName}. Please contact your administrator for assistance.`;
384+
},
377385
},
378386
media: {
379387
clickToUpload: 'Click to upload',
@@ -2736,6 +2744,9 @@ export default {
27362744
routing: {
27372745
routeNotFoundTitle: 'Not found',
27382746
routeNotFoundDescription: 'The requested route could not be found. Please check the URL and try again.',
2747+
routeForbiddenTitle: 'Access denied',
2748+
routeForbiddenDescription:
2749+
'You do not have permission to access this resource. Please contact your administrator for assistance.',
27392750
},
27402751
codeEditor: {
27412752
label: 'Code editor',

src/Umbraco.Web.UI.Client/src/mocks/browser-handlers.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import * as manifestsHandlers from './handlers/manifests.handlers.js';
3939
import * as serverHandlers from './handlers/server.handlers.js';
4040
import { handlers as documentBlueprintHandlers } from './handlers/document-blueprint/index.js';
4141
import { handlers as temporaryFileHandlers } from './handlers/temporary-file/index.js';
42+
import { handlers as segmentHandlers } from './handlers/segment.handlers.js';
4243

4344
const handlers = [
4445
...backofficeHandlers,
@@ -80,6 +81,7 @@ const handlers = [
8081
...userHandlers,
8182
...documentBlueprintHandlers,
8283
...temporaryFileHandlers,
84+
...segmentHandlers,
8385
...serverHandlers.serverInformationHandlers,
8486
serverHandlers.serverRunningHandler,
8587
...manifestsHandlers.manifestEmptyHandlers,

src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ export const data: Array<UmbMockDataTypeModel> = [
3131
isDeletable: true,
3232
canIgnoreStartNodes: false,
3333
},
34+
{
35+
id: 'forbidden',
36+
parent: null,
37+
name: 'Forbidden Data Type',
38+
editorAlias: 'Umbraco.TextBox',
39+
editorUiAlias: 'Umb.PropertyEditorUi.TextBox',
40+
values: [],
41+
hasChildren: false,
42+
isFolder: false,
43+
isDeletable: true,
44+
canIgnoreStartNodes: false,
45+
},
3446
{
3547
id: '0cc0eba1-9960-42c9-bf9b-60e150b429ae',
3648
parent: null,

src/Umbraco.Web.UI.Client/src/mocks/data/dictionary/dictionary.data.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,23 @@ export type UmbMockDictionaryModel = DictionaryItemResponseModel &
1111
DictionaryOverviewResponseModel;
1212

1313
export const data: Array<UmbMockDictionaryModel> = [
14+
{
15+
name: 'Forbidden',
16+
id: 'forbidden',
17+
parent: null,
18+
hasChildren: false,
19+
translatedIsoCodes: ['en-us'],
20+
translations: [
21+
{
22+
isoCode: 'en-us',
23+
translation: 'This is a forbidden dictionary item',
24+
},
25+
{
26+
isoCode: 'da',
27+
translation: 'Dette er et forbudt ordbogsobjekt',
28+
},
29+
],
30+
},
1431
{
1532
name: 'Hello',
1633
id: 'aae7d0ab-53ba-485d-b8bd-12537f9925cb',

src/Umbraco.Web.UI.Client/src/mocks/data/document-blueprint/document-blueprint.data.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const data: Array<UmbMockDocumentBlueprintModel> = [
1818
},
1919
hasChildren: false,
2020
isFolder: false,
21+
parent: null,
2122
name: 'The Simplest Document Blueprint',
2223
variants: [
2324
{
@@ -40,4 +41,35 @@ export const data: Array<UmbMockDocumentBlueprintModel> = [
4041
},
4142
],
4243
},
44+
{
45+
id: 'forbidden',
46+
documentType: {
47+
id: 'the-simplest-document-type-id',
48+
icon: 'icon-document',
49+
},
50+
hasChildren: false,
51+
isFolder: false,
52+
parent: null,
53+
name: 'A Forbidden Document Blueprint',
54+
variants: [
55+
{
56+
state: DocumentVariantStateModel.DRAFT,
57+
publishDate: '2023-02-06T15:32:24.957009',
58+
culture: 'en-US',
59+
segment: null,
60+
name: 'A Forbidden Document Blueprint',
61+
createDate: '2023-02-06T15:32:05.350038',
62+
updateDate: '2023-02-06T15:32:24.957009',
63+
},
64+
],
65+
values: [
66+
{
67+
editorAlias: 'Umbraco.TextBox',
68+
alias: 'prop1',
69+
culture: null,
70+
segment: null,
71+
value: 'my blueprint value',
72+
},
73+
],
74+
},
4375
];

src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.data.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,4 +1870,58 @@ export const data: Array<UmbMockDocumentTypeModel> = [
18701870
keepLatestVersionPerDayForDays: null,
18711871
},
18721872
},
1873+
{
1874+
allowedTemplates: [],
1875+
defaultTemplate: { id: 'the-simplest-document-type-id' },
1876+
id: 'forbidden',
1877+
alias: 'forbidden',
1878+
name: 'A forbidden document type',
1879+
description: null,
1880+
icon: 'icon-document',
1881+
allowedAsRoot: true,
1882+
variesByCulture: false,
1883+
variesBySegment: false,
1884+
isElement: false,
1885+
hasChildren: false,
1886+
parent: null,
1887+
isFolder: false,
1888+
properties: [
1889+
{
1890+
id: '1680d4d2-cda8-4ac2-affd-a69fc10382b1',
1891+
container: { id: 'the-simplest-document-type-id-container' },
1892+
alias: 'prop1',
1893+
name: 'Prop 1',
1894+
description: null,
1895+
dataType: { id: '0cc0eba1-9960-42c9-bf9b-60e150b429ae' },
1896+
variesByCulture: false,
1897+
variesBySegment: false,
1898+
sortOrder: 0,
1899+
validation: {
1900+
mandatory: false,
1901+
mandatoryMessage: null,
1902+
regEx: null,
1903+
regExMessage: null,
1904+
},
1905+
appearance: {
1906+
labelOnTop: false,
1907+
},
1908+
},
1909+
],
1910+
containers: [
1911+
{
1912+
id: 'the-simplest-document-type-id-container',
1913+
parent: null,
1914+
name: 'Content',
1915+
type: 'Group',
1916+
sortOrder: 0,
1917+
},
1918+
],
1919+
allowedDocumentTypes: [],
1920+
compositions: [],
1921+
cleanup: {
1922+
preventCleanup: false,
1923+
keepAllVersionsNewerThanDays: null,
1924+
keepLatestVersionPerDayForDays: null,
1925+
},
1926+
},
18731927
];

src/Umbraco.Web.UI.Client/src/mocks/data/document/document.data.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const data: Array<UmbMockDocumentModel> = [
2828
{
2929
state: DocumentVariantStateModel.DRAFT,
3030
publishDate: '2023-02-06T15:32:24.957009',
31-
culture: 'en-us',
31+
culture: 'en-US',
3232
segment: null,
3333
name: 'The Simplest Document',
3434
createDate: '2023-02-06T15:32:05.350038',
@@ -1227,5 +1227,50 @@ export const data: Array<UmbMockDocumentModel> = [
12271227
},
12281228
],
12291229
},
1230+
{
1231+
ancestors: [],
1232+
urls: [],
1233+
template: null,
1234+
id: 'forbidden',
1235+
createDate: '2023-02-06T15:32:05.350038',
1236+
parent: null,
1237+
documentType: {
1238+
id: 'the-simplest-document-type-id',
1239+
icon: 'icon-document',
1240+
},
1241+
hasChildren: false,
1242+
noAccess: false,
1243+
isProtected: false,
1244+
isTrashed: false,
1245+
variants: [
1246+
{
1247+
state: DocumentVariantStateModel.PUBLISHED,
1248+
publishDate: '2023-02-06T15:32:24.957009',
1249+
culture: 'en-US',
1250+
segment: null,
1251+
name: 'A forbidden document',
1252+
createDate: '2023-02-06T15:32:05.350038',
1253+
updateDate: '2023-02-06T15:32:24.957009',
1254+
},
1255+
{
1256+
state: DocumentVariantStateModel.PUBLISHED,
1257+
publishDate: '2023-02-06T15:32:24.957009',
1258+
culture: 'da-dk',
1259+
segment: null,
1260+
name: 'Et utilgængeligt dokument',
1261+
createDate: '2023-02-06T15:32:05.350038',
1262+
updateDate: '2023-02-06T15:32:24.957009',
1263+
},
1264+
],
1265+
values: [
1266+
{
1267+
editorAlias: 'Umbraco.TextBox',
1268+
alias: 'prop1',
1269+
culture: null,
1270+
segment: null,
1271+
value: 'default value here',
1272+
},
1273+
],
1274+
},
12301275
...permissionsTestData,
12311276
];

src/Umbraco.Web.UI.Client/src/mocks/data/language/language.data.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,10 @@ export const data: Array<UmbMockLanguageModel> = [
1616
isMandatory: false,
1717
fallbackIsoCode: 'en-US',
1818
},
19+
{
20+
name: 'Forbidden',
21+
isoCode: 'forbidden',
22+
isDefault: false,
23+
isMandatory: false,
24+
},
1925
];

0 commit comments

Comments
 (0)