From 61014f1bc452168f3bd863ce00221d28fea8036f Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sat, 3 Oct 2020 12:42:14 +0200 Subject: [PATCH 01/10] Update NotePermissionsUpdate DTOs to be aware of groups The NotePermissionsUpdateDto was not updated when group permissions were introduced. Signed-off-by: David Mehren Co-authored-by: Yannick Bungers --- src/notes/note-permissions.dto.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/notes/note-permissions.dto.ts b/src/notes/note-permissions.dto.ts index 8df0aa894..e6a079976 100644 --- a/src/notes/note-permissions.dto.ts +++ b/src/notes/note-permissions.dto.ts @@ -8,7 +8,7 @@ export class NoteUserPermissionEntryDto { canEdit: boolean; } -export class NotePermissionEntryUpdateDto { +export class NoteUserPermissionUpdateDto { @IsString() username: string; @IsBoolean() @@ -31,6 +31,13 @@ export class NoteGroupPermissionEntryDto { canEdit: boolean; } +export class NoteGroupPermissionUpdateDto { + @IsString() + groupname: string; + @IsBoolean() + canEdit: boolean; +} + export class NotePermissionsDto { @ValidateNested() owner: UserInfoDto; @@ -45,5 +52,8 @@ export class NotePermissionsDto { export class NotePermissionsUpdateDto { @IsArray() @ValidateNested() - sharedTo: NotePermissionEntryUpdateDto[]; + sharedToUsers: NoteUserPermissionUpdateDto[]; + @IsArray() + @ValidateNested() + sharedToGroups: NoteGroupPermissionUpdateDto[]; } From 2be1defd7ac8100a7ca68d3f84f0996f8339649b Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sat, 3 Oct 2020 12:46:28 +0200 Subject: [PATCH 02/10] Public API: Split-out a /notes/{note}/permissions route to set only permissions Previously, the metadata route was used to both update note metadata (like title, description and tags) and the permissions. Additionally, one had to send many unchangeable properties. In this commit, a /notes/{note}/permissions route is introduced, that only changes permissions. Additionally, PUT /notes/{note}/metadata now needs only the properties that are actually changeable. Signed-off-by: David Mehren Co-authored-by: Yannick Bungers --- docs/dev/public_api.yml | 116 +++++++++++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 14 deletions(-) diff --git a/docs/dev/public_api.yml b/docs/dev/public_api.yml index fecc46375..987aceef3 100644 --- a/docs/dev/public_api.yml +++ b/docs/dev/public_api.yml @@ -307,17 +307,43 @@ paths: put: tags: - note - summary: Set the permissions of a note + summary: Set the metadata (title, description, tags) of a note operationId: updateNoteMetadata requestBody: required: true content: application/json: schema: - "$ref": "#/components/schemas/NoteMetadata" + "$ref": "#/components/schemas/NoteMetadataUpdate" responses: '200': - description: The updated permissions of the note. + description: The updated metadata of the note. + content: + application/json: + schema: + "$ref": "#/components/schemas/NoteMetadataUpdate" + '401': + "$ref": "#/components/responses/UnauthorizedError" + '403': + "$ref": "#/components/responses/ForbiddenError" + '404': + "$ref": "#/components/responses/NotFoundError" + parameters: + - name: note + in: path + required: true + description: The note for which the info should be shown. + content: + text/plain: + example: my-note + get: + tags: + - note + summary: Get the metadata of a note + operationId: getNoteMetadata + responses: + '200': + description: The metadata of the note. content: application/json: schema: @@ -336,18 +362,24 @@ paths: content: text/plain: example: my-note - get: - tags: - - note - summary: Get the permissions of a note - operationId: getNoteMetadata + /notes/{note}/permissions: + put: + tags: [ note ] + summary: Set permissions of a note + operationId: updateNotePermissions + requestBody: + required: true + content: + application/json: + schema: + "$ref": "#/components/schemas/NotePermissionsUpdate" responses: '200': - description: The permissions of the note. + description: The updated permissions of the note. content: application/json: schema: - "$ref": "#/components/schemas/NoteMetadata" + "$ref": "#/components/schemas/NotePermissionsUpdate" '401': "$ref": "#/components/responses/UnauthorizedError" '403': @@ -614,6 +646,15 @@ components: properties: password: type: string + GroupInfo: + type: object + properties: + name: + type: string + displayName: + type: string + special: + type: boolean ImageProxyRequest: type: object properties: @@ -681,13 +722,51 @@ components: type: string permissions: $ref: "#/components/schemas/NotePermissions" + NoteMetadataUpdate: + type: object + description: Contains only title, description and tags of a note. + properties: + title: + type: string + description: Title of the note + description: + type: string + description: Description of the note. + tags: + type: array + description: A list of tags attached to the note. + items: + type: string NotePermissions: type: object properties: owner: - type: string - description: Username of the owner of the note - sharedTo: + $ref: "#/components/schemas/UserInfo" + sharedToUsers: + type: array + description: Contains all users that can read the note and a boolean that denotes if they can also edit. + items: + type: object + properties: + user: + $ref: "#/components/schemas/UserInfo" + canEdit: + type: boolean + sharedToGroups: + type: array + description: Contains all groups that can read the note and a boolean that denotes if they can also edit. + items: + type: object + properties: + group: + $ref: "#/components/schemas/GroupInfo" + canEdit: + type: boolean + NotePermissionsUpdate: + type: object + description: Contains only title, description and tags of a note. + properties: + sharedToUsers: type: array description: Contains all usernames that can read the note and a boolean that denotes if they can also edit. items: @@ -697,7 +776,16 @@ components: type: string canEdit: type: boolean - + sharedToGroups: + type: array + description: Contains all groups that can read the note and a boolean that denotes if they can also edit. + items: + type: object + properties: + groupname: + type: string + canEdit: + type: boolean NoteRevisionsMetadata: type: array items: From b63593aa8b9a9684576029cf36a0f0e076f6bf96 Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sat, 3 Oct 2020 12:49:50 +0200 Subject: [PATCH 03/10] Public API: Simplify PUT /me/history/{note} Previously, one had to send a complete `NoteMetadata` object when updating the pinned status of a note. A new `HistoryUpdateObject` type was introduced, that only contains the pinned status boolean. Signed-off-by: David Mehren Co-authored-by: Yannick Bungers --- docs/dev/public_api.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/dev/public_api.yml b/docs/dev/public_api.yml index 987aceef3..6e35f9bdd 100644 --- a/docs/dev/public_api.yml +++ b/docs/dev/public_api.yml @@ -88,7 +88,7 @@ paths: content: application/json: schema: - "$ref": "#/components/schemas/HistoryObject" + "$ref": "#/components/schemas/HistoryUpdateObject" responses: '200': description: The new history. @@ -908,6 +908,12 @@ components: pinned: type: boolean description: Whether the user has pinned this note. + HistoryUpdateObject: + type: object + properties: + pinned: + type: boolean + description: Whether the user has pinned this note. History: type: object properties: From 67633c375db5c3af2d5b9589c2fd092a89dbae25 Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sat, 3 Oct 2020 14:40:51 +0200 Subject: [PATCH 04/10] Public API: Successful POST requests should result in a 201. Signed-off-by: David Mehren Co-authored-by: Yannick Bungers --- docs/dev/public_api.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/dev/public_api.yml b/docs/dev/public_api.yml index 6e35f9bdd..eef797654 100644 --- a/docs/dev/public_api.yml +++ b/docs/dev/public_api.yml @@ -169,7 +169,7 @@ paths: markdownExample: "$ref": '#/components/examples/markdownExample' responses: - '200': + '201': description: Get information about the newly created note. content: application/json: @@ -224,7 +224,7 @@ paths: markdownExample: "$ref": '#/components/examples/markdownExample' responses: - '200': + '201': description: Get information about the newly created note. content: application/json: @@ -556,7 +556,7 @@ paths: required: true description: ID or alias of the parent note responses: - '200': + '201': description: The file was uploaded successfully. content: application/json: From be5b6dcf0ec0bd0265b0b8c3cb92cf8dcd082093 Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sat, 3 Oct 2020 14:45:04 +0200 Subject: [PATCH 05/10] NoteMetadataDto: Rename `permission` to `permissions` Signed-off-by: David Mehren Co-authored-by: Yannick Bungers --- src/history/history.service.ts | 4 ++-- src/notes/note-metadata.dto.ts | 2 +- src/notes/notes.service.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/history/history.service.ts b/src/history/history.service.ts index d8ab04adf..7a4b7f7e4 100644 --- a/src/history/history.service.ts +++ b/src/history/history.service.ts @@ -20,7 +20,7 @@ export class HistoryService { description: 'Very descriptive text.', editedBy: [], id: 'foobar-barfoo', - permission: { + permissions: { owner: { displayName: 'foo', userName: 'fooUser', @@ -59,7 +59,7 @@ export class HistoryService { description: 'Very descriptive text.', editedBy: [], id: 'foobar-barfoo', - permission: { + permissions: { owner: { displayName: 'foo', userName: 'fooUser', diff --git a/src/notes/note-metadata.dto.ts b/src/notes/note-metadata.dto.ts index b68d0aef9..2b26a37bb 100644 --- a/src/notes/note-metadata.dto.ts +++ b/src/notes/note-metadata.dto.ts @@ -32,5 +32,5 @@ export class NoteMetadataDto { @ValidateNested() editedBy: UserInfoDto['userName'][]; @ValidateNested() - permission: NotePermissionsDto; + permissions: NotePermissionsDto; } diff --git a/src/notes/notes.service.ts b/src/notes/notes.service.ts index b31d5c05f..8290bc04e 100644 --- a/src/notes/notes.service.ts +++ b/src/notes/notes.service.ts @@ -37,7 +37,7 @@ export class NotesService { description: 'Very descriptive text.', editedBy: [], id: 'foobar-barfoo', - permission: { + permissions: { owner: { displayName: 'foo', userName: 'fooUser', @@ -108,7 +108,7 @@ export class NotesService { description: NoteUtils.parseDescription(note), editedBy: note.authorColors.map(authorColor => authorColor.user.userName), // TODO: Extract into method - permission: { + permissions: { owner: this.usersService.toUserDto(note.owner), sharedToUsers: note.userPermissions.map(noteUserPermission => ({ user: this.usersService.toUserDto(noteUserPermission.user), From a640dea1aa643e8ad98c575209784901d96370d6 Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sat, 3 Oct 2020 14:51:22 +0200 Subject: [PATCH 06/10] Public API: Update description of /notes/{note} POST and PUT routes. Signed-off-by: David Mehren Co-authored-by: Yannick Bungers --- docs/dev/public_api.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dev/public_api.yml b/docs/dev/public_api.yml index eef797654..4f33f4110 100644 --- a/docs/dev/public_api.yml +++ b/docs/dev/public_api.yml @@ -212,7 +212,7 @@ paths: - note summary: Imports some markdown data into a new note with a given alias operationId: createNoteWithAlias - description: This endpoint equals to the above one except that the alias from the url will be assigned to the note if [FreeURL-mode](https://github.com/codimd/server/tree/master/docs/configuration-env-vars.md#users-and-privileges) is enabled. + description: This endpoint creates a new note with the content of the HTTP request body and the alias from the URL parameter. requestBody: required: true description: The content of the note to be imported as markdown. @@ -271,7 +271,7 @@ paths: - note summary: Imports some markdown data into an existing note, creating a new revision operationId: createNewRevisionForNote - description: This endpoint equals to the above one except that the alias from the url will be assigned to the note if [FreeURL-mode](https://github.com/codimd/server/tree/master/docs/configuration-env-vars.md#users-and-privileges) is enabled. + description: This endpoint updates the note content of an existing note. The old content is completely replaced and a new revision is created. requestBody: required: true description: The content of the note to be imported as markdown. From 7adcad2ce6fac352b6af6ec9e5cd5af608f48a1f Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sat, 3 Oct 2020 18:08:31 +0200 Subject: [PATCH 07/10] Public API: Fix `PUT /notes/{note}/permissions` response This route should return a full `NotePermissions` object instead of only `NotePermissionsUpdate` Signed-off-by: David Mehren Co-authored-by: Yannick Bungers --- docs/dev/public_api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/public_api.yml b/docs/dev/public_api.yml index 4f33f4110..790476ed0 100644 --- a/docs/dev/public_api.yml +++ b/docs/dev/public_api.yml @@ -379,7 +379,7 @@ paths: content: application/json: schema: - "$ref": "#/components/schemas/NotePermissionsUpdate" + "$ref": "#/components/schemas/NotePermissions" '401': "$ref": "#/components/responses/UnauthorizedError" '403': From a4ac295adaac301605ae47935dbd2bd1a3cc16cd Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sat, 24 Oct 2020 19:25:15 +0200 Subject: [PATCH 08/10] Public API: Remove `PUT /notes/{note}/metadata` The note metadata will be automatically extracted from the note content and cannot be updated separately. Signed-off-by: David Mehren Co-authored-by: Yannick Bungers --- docs/dev/public_api.yml | 47 ----------------------------------------- 1 file changed, 47 deletions(-) diff --git a/docs/dev/public_api.yml b/docs/dev/public_api.yml index 790476ed0..62d224046 100644 --- a/docs/dev/public_api.yml +++ b/docs/dev/public_api.yml @@ -304,38 +304,6 @@ paths: text/plain: example: my-note /notes/{note}/metadata: - put: - tags: - - note - summary: Set the metadata (title, description, tags) of a note - operationId: updateNoteMetadata - requestBody: - required: true - content: - application/json: - schema: - "$ref": "#/components/schemas/NoteMetadataUpdate" - responses: - '200': - description: The updated metadata of the note. - content: - application/json: - schema: - "$ref": "#/components/schemas/NoteMetadataUpdate" - '401': - "$ref": "#/components/responses/UnauthorizedError" - '403': - "$ref": "#/components/responses/ForbiddenError" - '404': - "$ref": "#/components/responses/NotFoundError" - parameters: - - name: note - in: path - required: true - description: The note for which the info should be shown. - content: - text/plain: - example: my-note get: tags: - note @@ -722,21 +690,6 @@ components: type: string permissions: $ref: "#/components/schemas/NotePermissions" - NoteMetadataUpdate: - type: object - description: Contains only title, description and tags of a note. - properties: - title: - type: string - description: Title of the note - description: - type: string - description: Description of the note. - tags: - type: array - description: A list of tags attached to the note. - items: - type: string NotePermissions: type: object properties: From cfe8169fc2729f11418019fb2fe78ce51d15765b Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sat, 24 Oct 2020 19:39:05 +0200 Subject: [PATCH 09/10] Public API: `NoteRevisionsMetadata` is not an array Signed-off-by: David Mehren Co-authored-by: Yannick Bungers --- docs/dev/public_api.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/dev/public_api.yml b/docs/dev/public_api.yml index 62d224046..d2b95130b 100644 --- a/docs/dev/public_api.yml +++ b/docs/dev/public_api.yml @@ -375,7 +375,9 @@ paths: content: application/json: schema: - "$ref": "#/components/schemas/NoteRevisionsMetadata" + type: array + items: + "$ref": "#/components/schemas/NoteRevisionsMetadata" '401': "$ref": "#/components/responses/UnauthorizedError" '403': @@ -740,19 +742,17 @@ components: canEdit: type: boolean NoteRevisionsMetadata: - type: array - items: - type: object - properties: - id: - type: integer - description: The id of the revision - createdTime: - type: string - description: ISO-timestamp of when the revision was saved. Is also the revision-id. - length: - type: integer - description: Length of the document to the timepoint the revision was saved. + type: object + properties: + id: + type: integer + description: The id of the revision + createdTime: + type: string + description: ISO-timestamp of when the revision was saved. Is also the revision-id. + length: + type: integer + description: Length of the document to the timepoint the revision was saved. NoteRevision: type: object properties: From b7195c563c39af85803cee72f88a0cd081f42583 Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sat, 24 Oct 2020 19:39:34 +0200 Subject: [PATCH 10/10] Public API: Cleanup history schemas Signed-off-by: David Mehren Co-authored-by: Yannick Bungers --- docs/dev/public_api.yml | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/docs/dev/public_api.yml b/docs/dev/public_api.yml index d2b95130b..199addd33 100644 --- a/docs/dev/public_api.yml +++ b/docs/dev/public_api.yml @@ -47,7 +47,9 @@ paths: content: application/json: schema: - "$ref": "#/components/schemas/History" + type: array + items: + "$ref": "#/components/schemas/History" '401': "$ref": "#/components/responses/UnauthorizedError" /me/history/{note}: @@ -60,11 +62,11 @@ paths: description: JSON Object which contains id, title, tags, last visit time and pinned status responses: '200': - description: The list of recently viewed notes and pinned notes. + description: Information about the history entry content: application/json: schema: - "$ref": "#/components/schemas/HistoryObject" + "$ref": "#/components/schemas/History" '401': "$ref": "#/components/responses/UnauthorizedError" '404': @@ -88,7 +90,7 @@ paths: content: application/json: schema: - "$ref": "#/components/schemas/HistoryUpdateObject" + "$ref": "#/components/schemas/HistoryUpdate" responses: '200': description: The new history. @@ -853,7 +855,7 @@ components: type: boolean disconnectSocketQueueLength: type: integer - HistoryObject: + History: type: object properties: metadata: @@ -861,20 +863,12 @@ components: pinned: type: boolean description: Whether the user has pinned this note. - HistoryUpdateObject: + HistoryUpdate: type: object properties: pinned: type: boolean description: Whether the user has pinned this note. - History: - type: object - properties: - history: - type: array - description: The array that contains history objects. - items: - "$ref": "#/components/schemas/HistoryObject" examples: markdownExample: value: '# Some header\nSome normal text. **Some bold text**'