Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: User Permissions WIP part 1 #881

Merged
merged 108 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
c12fa8f
set up new permission extension model
madsrasmussen Sep 7, 2023
388e7ae
register first document permissions
madsrasmussen Sep 7, 2023
26e7d8d
Merge branch 'bugfix-user-group-workspace-missing-entity-type' into f…
madsrasmussen Sep 7, 2023
f6b953a
Merge branch 'main' into feature/permissions
madsrasmussen Sep 7, 2023
e500b96
temp render registered permissions
madsrasmussen Sep 7, 2023
3dc8d82
remove unused import
madsrasmussen Sep 7, 2023
5ea9b08
add more document permissions
madsrasmussen Sep 7, 2023
e3fbe20
update label
madsrasmussen Sep 7, 2023
69825ea
rename to user permission
madsrasmussen Sep 7, 2023
db3e7ad
move into document folder
madsrasmussen Sep 7, 2023
528a4c5
rename extension type to user permission
madsrasmussen Sep 7, 2023
0dcd726
move renaming
madsrasmussen Sep 7, 2023
253f2e3
add methods to update user group permissions
madsrasmussen Sep 7, 2023
b83811a
move permission list to component + add mock data to persist save
madsrasmussen Sep 7, 2023
ed4df89
add type to import
madsrasmussen Sep 8, 2023
c6569f8
add condition to entity action
madsrasmussen Sep 8, 2023
860e66c
scaffold user permission condition
madsrasmussen Sep 8, 2023
69a199f
expose manifest
madsrasmussen Sep 8, 2023
3d149fb
rename to auth context
madsrasmussen Sep 8, 2023
62d809c
format
madsrasmussen Sep 8, 2023
4529321
check for user permission in condition
madsrasmussen Sep 8, 2023
bf5103f
clean up
madsrasmussen Sep 8, 2023
37fac1c
Merge branch 'main' into feature/permissions
madsrasmussen Sep 8, 2023
65fe97d
Merge branch 'main' into feature/permissions
madsrasmussen Sep 8, 2023
07fe7a2
Merge branch 'main' into feature/permissions
madsrasmussen Sep 13, 2023
52b260c
Merge branch 'main' into feature/permissions
madsrasmussen Sep 18, 2023
a5c0248
manual merge
madsrasmussen Sep 18, 2023
6bf3b99
remove s from file name
madsrasmussen Sep 18, 2023
91438fd
use singular form
madsrasmussen Sep 18, 2023
1bba424
clean up
madsrasmussen Sep 18, 2023
cc34f45
add method to get permissions
madsrasmussen Sep 18, 2023
b7d8be2
add const for document user permission alias'
madsrasmussen Sep 18, 2023
265508d
use permission const in mock data
madsrasmussen Sep 18, 2023
4ffa8ba
fix styling
madsrasmussen Sep 18, 2023
d35167e
add new granular user permission extension type
madsrasmussen Sep 18, 2023
686bb56
register granular permission for documents
madsrasmussen Sep 18, 2023
94e9dce
export granular permission manifest
madsrasmussen Sep 18, 2023
2312e4f
render granular permission extensions
madsrasmussen Sep 19, 2023
47a052a
add entity type to document permissions
madsrasmussen Sep 19, 2023
3feb350
Merge branch 'main' into feature/permissions
madsrasmussen Sep 25, 2023
94ef966
add scaffold for common dialog to get permission based on an entity t…
madsrasmussen Sep 25, 2023
a0dea29
wip granular permissions for documents
madsrasmussen Sep 25, 2023
6045387
add selected event
madsrasmussen Sep 25, 2023
1d16f34
use selected event when selecting tree items
madsrasmussen Sep 25, 2023
d036b10
format
madsrasmussen Sep 25, 2023
738010d
dispatch selected event from tree picker modal
madsrasmussen Sep 25, 2023
1102097
format
madsrasmussen Sep 25, 2023
a0dfc9e
export modules in user package
madsrasmussen Sep 26, 2023
04c7ed6
register entry point
madsrasmussen Sep 26, 2023
d5d6b7b
clean up
madsrasmussen Sep 26, 2023
ec7f84d
don't add type to UserStateModel
madsrasmussen Sep 26, 2023
95165b8
format
madsrasmussen Sep 26, 2023
3a18351
add user group item handler
madsrasmussen Sep 26, 2023
7a39d55
add methods to get user group items
madsrasmussen Sep 26, 2023
4cc351f
export components from user module
madsrasmussen Sep 26, 2023
cf6ace7
add handlers to get user items
madsrasmussen Sep 26, 2023
82dc218
we don't need the repository here
madsrasmussen Sep 26, 2023
aa30a01
add mocks
madsrasmussen Sep 26, 2023
a387681
load components as part of manifest ts
madsrasmussen Sep 26, 2023
42b2559
fix ts erros
madsrasmussen Sep 26, 2023
c702d69
only allow one entityType per permission
madsrasmussen Sep 26, 2023
e1e95d5
add a couple of media user permissions
madsrasmussen Sep 26, 2023
df0ee42
render entity type for user permissions
madsrasmussen Sep 26, 2023
94b8c32
localize entity groups
madsrasmussen Sep 26, 2023
d720ffb
Update user-group-default-permission-list.element.ts
madsrasmussen Sep 26, 2023
6fa7c06
add element to render a user-permission-setting
madsrasmussen Sep 26, 2023
630f5a1
add missing user permissions + add groups
madsrasmussen Sep 26, 2023
75fe7cf
Update user-group-default-permission-list.element.ts
madsrasmussen Sep 27, 2023
f6ddc14
format
madsrasmussen Sep 27, 2023
1d41368
render document input on user group
madsrasmussen Sep 27, 2023
e7f0911
dont show disable and enable button on current user profile page
JesmoDev Sep 27, 2023
5cbe644
Merge remote-tracking branch 'origin/feature/permissions' into featur…
JesmoDev Sep 27, 2023
441dcba
us ifDefined
madsrasmussen Sep 27, 2023
c599253
Merge branch 'feature/permissions' of https://github.com/umbraco/Umbr…
madsrasmussen Sep 27, 2023
bcc6753
remove debuggers
madsrasmussen Sep 27, 2023
60ed77d
update document input to use document input context
madsrasmussen Sep 27, 2023
8b7c82c
make init wait for promises
madsrasmussen Sep 27, 2023
b2931d1
register document item store
madsrasmussen Sep 27, 2023
b095a1d
align naming of element
madsrasmussen Sep 27, 2023
ef60560
export components from module
madsrasmussen Sep 27, 2023
8e112fe
update value on model
madsrasmussen Sep 27, 2023
4981436
add max 1 to document selector in user group workspace
JesmoDev Sep 27, 2023
cda4178
Merge remote-tracking branch 'origin/feature/permissions' into featur…
JesmoDev Sep 27, 2023
b51deb1
dispatch event when items are removed from a picker
madsrasmussen Sep 27, 2023
59d35b5
align methods
madsrasmussen Sep 27, 2023
eda4e0f
Merge branch 'feature/permissions' of https://github.com/umbraco/Umbr…
madsrasmussen Sep 27, 2023
cd9a15f
marked pre selected user in user picker modal
madsrasmussen Sep 27, 2023
6473eae
render input media on user group
madsrasmussen Sep 27, 2023
89b9f96
export / import input media from media package
madsrasmussen Sep 27, 2023
4b256a6
update media input to use picker context
madsrasmussen Sep 27, 2023
7f8857b
don't wrap in ref list
madsrasmussen Sep 27, 2023
6025bf7
handle media items
madsrasmussen Sep 27, 2023
ff2588e
add media change event
JesmoDev Sep 27, 2023
f4fc1b7
export components from media module
madsrasmussen Sep 27, 2023
c10a08f
don't request items if the array is empty
madsrasmussen Sep 27, 2023
ab0000a
init first
madsrasmussen Sep 27, 2023
6ff86fe
format
madsrasmussen Sep 27, 2023
0f2d403
stop events
madsrasmussen Sep 27, 2023
db6e7c0
update items when unique is empty
madsrasmussen Sep 27, 2023
7cac072
change user group actions to use entity actions
madsrasmussen Sep 27, 2023
906161a
add delete mock handler for user groups
madsrasmussen Sep 27, 2023
8c1f4d6
fix mock db delete method
madsrasmussen Sep 27, 2023
e65536b
split user group mocks into separate files
madsrasmussen Sep 27, 2023
8354d6f
don't return anything when deleting
madsrasmussen Sep 27, 2023
2b215bd
add wip alert
madsrasmussen Sep 27, 2023
1b5d3c6
add condition config to types
madsrasmussen Sep 27, 2023
3702397
temo ts-ignore
madsrasmussen Sep 27, 2023
f5fb8ce
comment out granular permission UI
madsrasmussen Sep 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/assets/lang/da-dk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,9 @@ export default {
permissionsDefault: 'Standardrettigheder',
permissionsGranular: 'Granulære rettigheder',
permissionsGranularHelp: 'Sæt rettigheder for specifikke noder',
permissionsEntityGroup_document: 'Indhold',
permissionsEntityGroup_media: 'Medie',
permissionsEntityGroup_member: 'Medlemmer',
profile: 'Profil',
searchAllChildren: "Søg alle 'børn'",
languagesHelp: 'Tilføj sprog for at give brugerne adgang til at redigere',
Expand Down
3 changes: 3 additions & 0 deletions src/assets/lang/en-us.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,9 @@ export default {
permissionsDefault: 'Default permissions',
permissionsGranular: 'Granular permissions',
permissionsGranularHelp: 'Set permissions for specific nodes',
permissionsEntityGroup_document: 'Content',
permissionsEntityGroup_media: 'Media',
permissionsEntityGroup_member: 'Member',
profile: 'Profile',
searchAllChildren: 'Search all children',
languagesHelp: 'Limit the languages users have access to edit',
Expand Down
2 changes: 1 addition & 1 deletion src/mocks/browser-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as serverHandlers from './handlers/server.handlers.js';
import { handlers as upgradeHandlers } from './handlers/upgrade.handlers.js';
import { handlers as userHandlers } from './handlers/user.handlers.js';
import { handlers as telemetryHandlers } from './handlers/telemetry.handlers.js';
import { handlers as userGroupsHandlers } from './handlers/user-group.handlers.js';
import { handlers as userGroupsHandlers } from './handlers/user-group/index.js';
import { handlers as examineManagementHandlers } from './handlers/examine-management.handlers.js';
import { handlers as modelsBuilderHandlers } from './handlers/modelsbuilder.handlers.js';
import { handlers as healthCheckHandlers } from './handlers/health-check.handlers.js';
Expand Down
11 changes: 1 addition & 10 deletions src/mocks/data/entity.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,10 @@ export class UmbEntityData<T extends UmbEntityBase> extends UmbData<T> {
}

delete(ids: Array<string>) {
const deletedKeys = this.data
.filter((item) => {
if (!item.id) throw new Error('Item has no id');
ids.includes(item.id);
})
.map((item) => item.id);

this.data = this.data.filter((item) => {
if (!item.id) throw new Error('Item has no id');
ids.indexOf(item.id) === -1;
return !ids.includes(item.id);
});

return deletedKeys;
}

updateData(updateItem: T) {
Expand Down
19 changes: 18 additions & 1 deletion src/mocks/data/media.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import type { MediaDetails } from '../../packages/media/media/index.js';
import { UmbEntityTreeData } from './entity-tree.data.js';
import { UmbEntityData } from './entity.data.js';
import { createContentTreeItem } from './utils.js';
import { ContentTreeItemResponseModel, PagedMediaTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
import {
ContentTreeItemResponseModel,
MediaItemResponseModel,
PagedMediaTreeItemResponseModel,
} from '@umbraco-cms/backoffice/backend-api';

export const data: Array<MediaDetails> = [
{
Expand Down Expand Up @@ -183,6 +187,14 @@ export const data: Array<MediaDetails> = [
},
];

const createMediaItem = (item: MediaDetails): MediaItemResponseModel => {
return {
id: item.id,
name: item.name,
icon: item.icon,
};
};

// Temp mocked database
// TODO: all properties are optional in the server schema. I don't think this is correct.
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Expand All @@ -194,6 +206,11 @@ class UmbMediaData extends UmbEntityData<MediaDetails> {
super(data);
}

getItems(ids: Array<string>): Array<MediaItemResponseModel> {
const items = this.data.filter((item) => ids.includes(item.id ?? ''));
return items.map((item) => createMediaItem(item));
}

getTreeRoot(): PagedMediaTreeItemResponseModel {
const items = this.data.filter((item) => item.parentId === null);
const treeItems = items.map((item) => createContentTreeItem(item));
Expand Down
78 changes: 78 additions & 0 deletions src/mocks/data/user-group.data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { UmbEntityData } from './entity.data.js';
import {
UMB_USER_PERMISSION_DOCUMENT_CREATE,
UMB_USER_PERMISSION_DOCUMENT_DELETE,
UMB_USER_PERMISSION_DOCUMENT_READ,
} from '@umbraco-cms/backoffice/document';
import {
PagedUserGroupResponseModel,
UserGroupItemResponseModel,
UserGroupResponseModel,
} from '@umbraco-cms/backoffice/backend-api';

const createUserGroupItem = (item: UserGroupResponseModel): UserGroupItemResponseModel => {
return {
name: item.name,
id: item.id,
icon: item.icon,
};
};

// Temp mocked database
class UmbUserGroupData extends UmbEntityData<UserGroupResponseModel> {
constructor(data: Array<UserGroupResponseModel>) {
super(data);
}

getAll(): PagedUserGroupResponseModel {
return {
total: this.data.length,
items: this.data,
};
}

getItems(ids: Array<string>): Array<UserGroupItemResponseModel> {
const items = this.data.filter((item) => ids.includes(item.id ?? ''));
return items.map((item) => createUserGroupItem(item));
}

/**
* Returns a list of permissions for the given user group ids
* @param {string[]} userGroupIds
* @return {*} {string[]}
* @memberof UmbUserGroupData
*/
getPermissions(userGroupIds: string[]): string[] {
const permissions = this.data
.filter((userGroup) => userGroupIds.includes(userGroup.id || ''))
.map((userGroup) => (userGroup.permissions?.length ? userGroup.permissions : []))
.flat();

// Remove duplicates
return [...new Set(permissions)];
}
}

export const data: Array<UserGroupResponseModel> = [
{
id: 'c630d49e-4e7b-42ea-b2bc-edc0edacb6b1',
name: 'Administrators',
icon: 'umb:medal',
documentStartNodeId: 'all-property-editors-document-id',
permissions: [UMB_USER_PERMISSION_DOCUMENT_CREATE, UMB_USER_PERMISSION_DOCUMENT_DELETE],
},
{
id: '9d24dc47-a4bf-427f-8a4a-b900f03b8a12',
name: 'User Group 1',
icon: 'umb:bell',
permissions: [UMB_USER_PERMISSION_DOCUMENT_DELETE],
},
{
id: 'f4626511-b0d7-4ab1-aebc-a87871a5dcfa',
name: 'User Group 2',
icon: 'umb:ball',
permissions: [UMB_USER_PERMISSION_DOCUMENT_READ],
},
];

export const umbUserGroupData = new UmbUserGroupData(data);
26 changes: 0 additions & 26 deletions src/mocks/data/user-groups.data.ts

This file was deleted.

113 changes: 35 additions & 78 deletions src/mocks/data/users.data.ts → src/mocks/data/user.data.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import { UmbData } from './data.js';
import { UmbEntityData } from './entity.data.js';
import { umbUserGroupData } from './user-group.data.js';
import { UmbLoggedInUser } from '@umbraco-cms/backoffice/auth';
import { PagedUserResponseModel, UserResponseModel, UserStateModel } from '@umbraco-cms/backoffice/backend-api';
import {
PagedUserResponseModel,
UpdateUserGroupsOnUserRequestModel,
UserItemResponseModel,
UserResponseModel,
UserStateModel,
} from '@umbraco-cms/backoffice/backend-api';

const createUserItem = (item: UserResponseModel): UserItemResponseModel => {
return {
name: item.name,
id: item.id,
};
};

// Temp mocked database
class UmbUsersData extends UmbData<UserResponseModel> {
class UmbUserData extends UmbEntityData<UserResponseModel> {
constructor(data: UserResponseModel[]) {
super(data);
}
Expand All @@ -15,12 +29,21 @@ class UmbUsersData extends UmbData<UserResponseModel> {
};
}

getById(id: string): UserResponseModel | undefined {
return this.data.find((user) => user.id === id);
getItems(ids: Array<string>): Array<UserItemResponseModel> {
const items = this.data.filter((item) => ids.includes(item.id ?? ''));
return items.map((item) => createUserItem(item));
}

setUserGroups(data: UpdateUserGroupsOnUserRequestModel): void {
const users = this.data.filter((user) => data.userIds?.includes(user.id ?? ''));
users.forEach((user) => {
user.userGroupIds = data.userGroupIds;
});
}

getCurrentUser(): UmbLoggedInUser {
const firstUser = this.data[0];
const permissions = firstUser.userGroupIds?.length ? umbUserGroupData.getPermissions(firstUser.userGroupIds) : [];

return {
id: firstUser.id,
Expand All @@ -33,79 +56,9 @@ class UmbUsersData extends UmbData<UserResponseModel> {
languages: [],
contentStartNodeIds: firstUser.contentStartNodeIds,
mediaStartNodeIds: firstUser.mediaStartNodeIds,
permissions: [],
permissions,
};
}

save(id: string, saveItem: UserResponseModel) {
const foundIndex = this.data.findIndex((item) => item.id === id);
if (foundIndex !== -1) {
// update
this.data[foundIndex] = saveItem;
this.updateData(saveItem);
} else {
// new
this.data.push(saveItem);
}

return saveItem;
}

protected updateData(updateItem: UserResponseModel) {
const itemIndex = this.data.findIndex((item) => item.id === updateItem.id);
const item = this.data[itemIndex];

console.log('updateData', updateItem, itemIndex, item);

if (!item) return;

const itemKeys = Object.keys(item);
const newItem = {};

for (const [key] of Object.entries(updateItem)) {
if (itemKeys.indexOf(key) !== -1) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
newItem[key] = updateItem[key];
}
}

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.data[itemIndex] = newItem;

console.log('updateData', this.data[itemIndex]);
}

// updateUserGroup(ids: string[], userGroup: string) {
// this.data.forEach((user) => {
// if (ids.includes(user.id)) {
// } else {
// }

// this.updateData(user);
// });

// return this.data.map((user) => user.id);
// }

// enable(ids: string[]) {
// const users = this.data.filter((user) => ids.includes(user.id));
// users.forEach((user) => {
// user.status = 'enabled';
// this.updateData(user);
// });
// return users.map((user) => user.id);
// }

// disable(ids: string[]) {
// const users = this.data.filter((user) => ids.includes(user.id));
// users.forEach((user) => {
// user.status = 'disabled';
// this.updateData(user);
// });
// return users.map((user) => user.id);
// }
}

export const data: Array<UserResponseModel & { type: string }> = [
Expand All @@ -124,7 +77,11 @@ export const data: Array<UserResponseModel & { type: string }> = [
updateDate: '2/10/2022',
createDate: '3/13/2022',
failedLoginAttempts: 946,
userGroupIds: ['c630d49e-4e7b-42ea-b2bc-edc0edacb6b1'],
userGroupIds: [
'c630d49e-4e7b-42ea-b2bc-edc0edacb6b1',
'9d24dc47-a4bf-427f-8a4a-b900f03b8a12',
'f4626511-b0d7-4ab1-aebc-a87871a5dcfa',
],
},
{
id: '82e11d3d-b91d-43c9-9071-34d28e62e81d',
Expand Down Expand Up @@ -196,4 +153,4 @@ export const data: Array<UserResponseModel & { type: string }> = [
},
];

export const umbUsersData = new UmbUsersData(data);
export const umbUsersData = new UmbUserData(data);
6 changes: 3 additions & 3 deletions src/mocks/handlers/dictionary.handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ export const handlers = [
const id = req.params.id as string;
if (!id) return;

const deletedKeys = umbDictionaryData.delete([id]);
umbDictionaryData.delete([id]);

return res(ctx.status(200), ctx.json(deletedKeys));
return res(ctx.status(200));
}),

// TODO => handle properly, querystring breaks handler
Expand All @@ -165,7 +165,7 @@ export const handlers = [
const item = umbDictionaryData.getById(id);

alert(
`Downloads file for dictionary "${item?.name}", ${includeChildren === 'true' ? 'with' : 'without'} children.`
`Downloads file for dictionary "${item?.name}", ${includeChildren === 'true' ? 'with' : 'without'} children.`,
);
return res(ctx.status(200));
}),
Expand Down
8 changes: 8 additions & 0 deletions src/mocks/handlers/media.handlers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
const { rest } = window.MockServiceWorker;
import { umbMediaData } from '../data/media.data.js';
import { umbracoPath } from '@umbraco-cms/backoffice/utils';

// TODO: add schema
export const handlers = [
rest.get(umbracoPath('/media/item'), (req, res, ctx) => {
const ids = req.url.searchParams.getAll('id');
if (!ids) return;
const items = umbMediaData.getItems(ids);
return res(ctx.status(200), ctx.json(items));
}),

rest.get('/umbraco/management/api/v1/media/details/:id', (req, res, ctx) => {
console.warn('Please move to schema');
const id = req.params.id as string;
Expand Down
Loading
Loading