mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-04-06 22:40:15 +00:00
Merge pull request #1794 from hedgedoc/addSpecialGroups
This commit is contained in:
commit
bb7561b9ad
9 changed files with 139 additions and 17 deletions
|
@ -9,7 +9,7 @@ import { getRepositoryToken } from '@nestjs/typeorm';
|
|||
import { Repository } from 'typeorm';
|
||||
|
||||
import appConfigMock from '../config/mock/app.config.mock';
|
||||
import { NotInDBError } from '../errors/errors';
|
||||
import { AlreadyInDBError, NotInDBError } from '../errors/errors';
|
||||
import { LoggerModule } from '../logger/logger.module';
|
||||
import { Group } from './group.entity';
|
||||
import { GroupsService } from './groups.service';
|
||||
|
@ -46,6 +46,33 @@ describe('GroupsService', () => {
|
|||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe('createGroup', () => {
|
||||
const groupName = 'testGroup';
|
||||
const displayname = 'Group Test';
|
||||
beforeEach(() => {
|
||||
jest
|
||||
.spyOn(groupRepo, 'save')
|
||||
.mockImplementationOnce(async (group: Group): Promise<Group> => group);
|
||||
});
|
||||
it('successfully creates a group', async () => {
|
||||
const user = await service.createGroup(groupName, displayname);
|
||||
expect(user.name).toEqual(groupName);
|
||||
expect(user.displayName).toEqual(displayname);
|
||||
});
|
||||
it('fails if group name is already taken', async () => {
|
||||
// add additional mock implementation for failure
|
||||
jest.spyOn(groupRepo, 'save').mockImplementationOnce(() => {
|
||||
throw new Error();
|
||||
});
|
||||
// create first group with group name
|
||||
await service.createGroup(groupName, displayname);
|
||||
// attempt to create second group with group name
|
||||
await expect(service.createGroup(groupName, displayname)).rejects.toThrow(
|
||||
AlreadyInDBError,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getGroupByName', () => {
|
||||
it('works', async () => {
|
||||
jest.spyOn(groupRepo, 'findOne').mockResolvedValueOnce(group);
|
||||
|
|
|
@ -7,7 +7,7 @@ import { Injectable } from '@nestjs/common';
|
|||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { NotInDBError } from '../errors/errors';
|
||||
import { AlreadyInDBError, NotInDBError } from '../errors/errors';
|
||||
import { ConsoleLoggerService } from '../logger/console-logger.service';
|
||||
import { GroupInfoDto } from './group-info.dto';
|
||||
import { Group } from './group.entity';
|
||||
|
@ -21,6 +21,35 @@ export class GroupsService {
|
|||
this.logger.setContext(GroupsService.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @async
|
||||
* Create a new group with a given name and displayName
|
||||
* @param name - the group name the new group shall have
|
||||
* @param displayName - the display name the new group shall have
|
||||
* @param special - if the group is special or not
|
||||
* @return {Group} the group
|
||||
* @throws {AlreadyInDBError} the group name is already taken.
|
||||
*/
|
||||
async createGroup(
|
||||
name: string,
|
||||
displayName: string,
|
||||
special = false,
|
||||
): Promise<Group> {
|
||||
const group = Group.create(name, displayName);
|
||||
group.special = special;
|
||||
try {
|
||||
return await this.groupRepository.save(group);
|
||||
} catch {
|
||||
this.logger.debug(
|
||||
`A group with the name '${name}' already exists.`,
|
||||
'createGroup',
|
||||
);
|
||||
throw new AlreadyInDBError(
|
||||
`A group with the name '${name}' already exists.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @async
|
||||
* Get a group by their name.
|
||||
|
|
10
src/groups/groups.special.ts
Normal file
10
src/groups/groups.special.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export enum SpecialGroup {
|
||||
LOGGED_IN = '_LOGGED_IN',
|
||||
EVERYONE = '_EVERYONE',
|
||||
}
|
|
@ -14,6 +14,7 @@ import { AuthConfig } from './config/auth.config';
|
|||
import { MediaConfig } from './config/media.config';
|
||||
import { ConsoleLoggerService } from './logger/console-logger.service';
|
||||
import { BackendType } from './media/backends/backend-type.enum';
|
||||
import { setupSpecialGroups } from './utils/createSpecialGroups';
|
||||
import { setupFrontendProxy } from './utils/frontend-integration';
|
||||
import { setupSessionMiddleware } from './utils/session';
|
||||
import { setupValidationPipe } from './utils/setup-pipes';
|
||||
|
@ -51,6 +52,8 @@ async function bootstrap(): Promise<void> {
|
|||
setupFrontendProxy(app, logger);
|
||||
}
|
||||
|
||||
await setupSpecialGroups(app);
|
||||
|
||||
setupSessionMiddleware(app, authConfig);
|
||||
|
||||
app.enableCors({
|
||||
|
|
|
@ -11,6 +11,7 @@ import { AuthToken } from '../auth/auth-token.entity';
|
|||
import { Author } from '../authors/author.entity';
|
||||
import appConfigMock from '../config/mock/app.config.mock';
|
||||
import { Group } from '../groups/group.entity';
|
||||
import { SpecialGroup } from '../groups/groups.special';
|
||||
import { Identity } from '../identity/identity.entity';
|
||||
import { LoggerModule } from '../logger/logger.module';
|
||||
import { Alias } from '../notes/alias.entity';
|
||||
|
@ -134,7 +135,7 @@ describe('PermissionsService', () => {
|
|||
note7.userPermissions.push(noteUserPermission2);
|
||||
|
||||
const everybody = {} as Group;
|
||||
everybody.name = 'everybody';
|
||||
everybody.name = SpecialGroup.EVERYONE;
|
||||
everybody.special = true;
|
||||
const noteEverybodyRead = createNote(user1);
|
||||
|
||||
|
@ -261,13 +262,19 @@ describe('PermissionsService', () => {
|
|||
function createGroups(): { [id: string]: Group } {
|
||||
const result: { [id: string]: Group } = {};
|
||||
|
||||
const everybody: Group = Group.create('everybody', 'Everybody');
|
||||
const everybody: Group = Group.create(
|
||||
SpecialGroup.EVERYONE,
|
||||
SpecialGroup.EVERYONE,
|
||||
);
|
||||
everybody.special = true;
|
||||
result['everybody'] = everybody;
|
||||
result[SpecialGroup.EVERYONE] = everybody;
|
||||
|
||||
const loggedIn = Group.create('loggedIn', 'loggedIn');
|
||||
const loggedIn = Group.create(
|
||||
SpecialGroup.LOGGED_IN,
|
||||
SpecialGroup.LOGGED_IN,
|
||||
);
|
||||
loggedIn.special = true;
|
||||
result['loggedIn'] = loggedIn;
|
||||
result[SpecialGroup.LOGGED_IN] = loggedIn;
|
||||
|
||||
const user1group = Group.create('user1group', 'user1group');
|
||||
user1group.members = [user1];
|
||||
|
@ -304,11 +311,23 @@ describe('PermissionsService', () => {
|
|||
return NoteGroupPermission.create(group, write);
|
||||
}
|
||||
|
||||
const everybodyRead = createNoteGroupPermission(groups['everybody'], false);
|
||||
const everybodyWrite = createNoteGroupPermission(groups['everybody'], true);
|
||||
const everybodyRead = createNoteGroupPermission(
|
||||
groups[SpecialGroup.EVERYONE],
|
||||
false,
|
||||
);
|
||||
const everybodyWrite = createNoteGroupPermission(
|
||||
groups[SpecialGroup.EVERYONE],
|
||||
true,
|
||||
);
|
||||
|
||||
const loggedInRead = createNoteGroupPermission(groups['loggedIn'], false);
|
||||
const loggedInWrite = createNoteGroupPermission(groups['loggedIn'], true);
|
||||
const loggedInRead = createNoteGroupPermission(
|
||||
groups[SpecialGroup.LOGGED_IN],
|
||||
false,
|
||||
);
|
||||
const loggedInWrite = createNoteGroupPermission(
|
||||
groups[SpecialGroup.LOGGED_IN],
|
||||
true,
|
||||
);
|
||||
|
||||
const user1groupRead = createNoteGroupPermission(
|
||||
groups['user1group'],
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { SpecialGroup } from '../groups/groups.special';
|
||||
import { Note } from '../notes/note.entity';
|
||||
import { User } from '../users/user.entity';
|
||||
|
||||
|
@ -102,16 +103,14 @@ export class PermissionsService {
|
|||
if (groupPermission.canEdit || !wantEdit) {
|
||||
// Handle special groups
|
||||
if (groupPermission.group.special) {
|
||||
if (groupPermission.group.name == 'loggedIn') {
|
||||
// TODO: Name of group for logged in users
|
||||
if (groupPermission.group.name == SpecialGroup.LOGGED_IN) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
groupPermission.group.name == 'everybody' &&
|
||||
groupPermission.group.name == SpecialGroup.EVERYONE &&
|
||||
(groupPermission.canEdit || !wantEdit) &&
|
||||
guestsAllowed
|
||||
) {
|
||||
// TODO: Name of group in which everybody even guests can edit
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -52,12 +52,13 @@ describe('UsersService', () => {
|
|||
.spyOn(userRepo, 'save')
|
||||
.mockImplementationOnce(async (user: User): Promise<User> => user);
|
||||
});
|
||||
it('works', async () => {
|
||||
it('successfully creates a user', async () => {
|
||||
const user = await service.createUser(username, displayname);
|
||||
expect(user.username).toEqual(username);
|
||||
expect(user.displayName).toEqual(displayname);
|
||||
});
|
||||
it('fails if username is already taken', async () => {
|
||||
// add additional mock implementation for failure
|
||||
jest.spyOn(userRepo, 'save').mockImplementationOnce(() => {
|
||||
throw new Error();
|
||||
});
|
||||
|
|
|
@ -26,7 +26,7 @@ export class UsersService {
|
|||
* @async
|
||||
* Create a new user with a given username and displayName
|
||||
* @param username - the username the new user shall have
|
||||
* @param displayName - the display the new user shall have
|
||||
* @param displayName - the display name the new user shall have
|
||||
* @return {User} the user
|
||||
* @throws {AlreadyInDBError} the username is already taken.
|
||||
*/
|
||||
|
|
34
src/utils/createSpecialGroups.ts
Normal file
34
src/utils/createSpecialGroups.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { NestExpressApplication } from '@nestjs/platform-express';
|
||||
|
||||
import { AlreadyInDBError } from '../errors/errors';
|
||||
import { GroupsService } from '../groups/groups.service';
|
||||
import { SpecialGroup } from '../groups/groups.special';
|
||||
|
||||
export async function setupSpecialGroups(
|
||||
app: NestExpressApplication,
|
||||
): Promise<void> {
|
||||
const groupService = app.get<GroupsService>(GroupsService);
|
||||
try {
|
||||
await groupService.createGroup(
|
||||
SpecialGroup.EVERYONE,
|
||||
SpecialGroup.EVERYONE,
|
||||
true,
|
||||
);
|
||||
await groupService.createGroup(
|
||||
SpecialGroup.LOGGED_IN,
|
||||
SpecialGroup.LOGGED_IN,
|
||||
true,
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof AlreadyInDBError) {
|
||||
// It's no problem if the special groups already exist
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue