From a37e9e74ff07b057370d1ed6c0b391a02be8a6d2 Mon Sep 17 00:00:00 2001 From: kontrollanten <6680299+kontrollanten@users.noreply.github.com> Date: Mon, 13 Dec 2021 15:29:13 +0100 Subject: [PATCH] Give moderators access to edit channels (#4608) * give admins access to edit all channels closes #4598 * test(channels): +admin update another users channel * Fix tests * fix(server): delete another users channel Since the channel owner isn't necessary the auth user we need to check the right account whether it's the last video or not. * REMOVE_ANY_VIDEO_CHANNEL > MANAGE_ANY_VIDEO_CHANNEL Merge REMOVE_ANY_VIDEO_CHANNEL and MANY_VIDEO_CHANNELS to MANAGE_ANY_VIDEO_CHANNEL. * user-right: moderator can't manage admins channel * client: MyVideoChannelCreateComponent > VideoChannelCreateComponent * client: MyVideoChannelEdit > VideoChannelEdit * Revert "user-right: moderator can't manage admins channel" This reverts commit 2c627c154e2bfe6af2e0f45efb27faf4117572f3. * server: clean dupl validator functionality * fix ensureUserCanManageChannel usage It's not async anymore. * server: merge channel validator middleares ensureAuthUserOwnsChannelValidator & ensureUserCanManageChannel gets merged into one middleware. * client(VideoChannelEdit): redirect to prev route * fix(VideoChannels): handle anon users * client: new routes for create/update channel * Refactor channel validators Co-authored-by: Chocobozzz --- .../src/app/+manage/manage-routing.module.ts | 31 +++++ client/src/app/+manage/manage.module.ts | 31 +++++ .../video-channel-create.component.ts} | 8 +- .../video-channel-edit.component.html | 96 +++++++++++++++ .../video-channel-edit.component.scss} | 4 + .../video-channel-edit/video-channel-edit.ts} | 2 +- .../video-channel-update.component.ts} | 19 +-- .../my-video-channel-edit.component.html | 112 ------------------ .../my-video-channels-routing.module.ts | 18 +-- .../my-video-channels.component.html | 4 +- .../my-video-channels.module.ts | 8 +- .../video-channels.component.html | 4 +- .../video-channels.component.ts | 10 +- .../+video-channels/video-channels.module.ts | 2 + client/src/app/app-routing.module.ts | 6 +- .../src/app/core/routing/redirect.service.ts | 6 +- server/controllers/activitypub/client.ts | 23 ++-- server/controllers/activitypub/inbox.ts | 14 ++- server/controllers/activitypub/outbox.ts | 13 +- server/controllers/api/video-channel.ts | 23 ++-- .../validators/shared/video-channels.ts | 7 -- server/middlewares/validators/users.ts | 17 +-- .../validators/videos/video-channels.ts | 60 +++------- server/tests/api/videos/video-channels.ts | 37 +++++- shared/core-utils/users/user-role.ts | 2 +- shared/extra-utils/users/users-command.ts | 3 +- shared/models/users/user-right.enum.ts | 2 +- 27 files changed, 316 insertions(+), 246 deletions(-) create mode 100644 client/src/app/+manage/manage-routing.module.ts create mode 100644 client/src/app/+manage/manage.module.ts rename client/src/app/{+my-library/+my-video-channels/my-video-channel-create.component.ts => +manage/video-channel-edit/video-channel-create.component.ts} (91%) create mode 100644 client/src/app/+manage/video-channel-edit/video-channel-edit.component.html rename client/src/app/{+my-library/+my-video-channels/my-video-channel-edit.component.scss => +manage/video-channel-edit/video-channel-edit.component.scss} (96%) rename client/src/app/{+my-library/+my-video-channels/my-video-channel-edit.ts => +manage/video-channel-edit/video-channel-edit.ts} (85%) rename client/src/app/{+my-library/+my-video-channels/my-video-channel-update.component.ts => +manage/video-channel-edit/video-channel-update.component.ts} (89%) delete mode 100644 client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html diff --git a/client/src/app/+manage/manage-routing.module.ts b/client/src/app/+manage/manage-routing.module.ts new file mode 100644 index 000000000..14ae4f1e0 --- /dev/null +++ b/client/src/app/+manage/manage-routing.module.ts @@ -0,0 +1,31 @@ +import { NgModule } from '@angular/core' +import { RouterModule, Routes } from '@angular/router' +import { VideoChannelCreateComponent } from './video-channel-edit/video-channel-create.component' +import { VideoChannelUpdateComponent } from './video-channel-edit/video-channel-update.component' + +const manageRoutes: Routes = [ + { + path: 'create', + component: VideoChannelCreateComponent, + data: { + meta: { + title: $localize`Create a new video channel` + } + } + }, + { + path: 'update/:videoChannelName', + component: VideoChannelUpdateComponent, + data: { + meta: { + title: $localize`Update video channel` + } + } + } +] + +@NgModule({ + imports: [ RouterModule.forChild(manageRoutes) ], + exports: [ RouterModule ] +}) +export class ManageRoutingModule {} diff --git a/client/src/app/+manage/manage.module.ts b/client/src/app/+manage/manage.module.ts new file mode 100644 index 000000000..28939ec5a --- /dev/null +++ b/client/src/app/+manage/manage.module.ts @@ -0,0 +1,31 @@ +import { NgModule } from '@angular/core' +import { SharedFormModule } from '@app/shared/shared-forms' +import { SharedGlobalIconModule } from '@app/shared/shared-icons' +import { SharedMainModule } from '@app/shared/shared-main' +import { SharedActorImageModule } from '../shared/shared-actor-image/shared-actor-image.module' +import { SharedActorImageEditModule } from '@app/shared/shared-actor-image-edit' +import { VideoChannelCreateComponent } from './video-channel-edit/video-channel-create.component' +import { VideoChannelUpdateComponent } from './video-channel-edit/video-channel-update.component' +import { ManageRoutingModule } from './manage-routing.module' + +@NgModule({ + imports: [ + ManageRoutingModule, + SharedMainModule, + SharedFormModule, + SharedGlobalIconModule, + SharedActorImageModule, + SharedActorImageEditModule + ], + + declarations: [ + VideoChannelCreateComponent, + VideoChannelUpdateComponent + ], + + exports: [ + ], + + providers: [] +}) +export class ManageModule { } diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts b/client/src/app/+manage/video-channel-edit/video-channel-create.component.ts similarity index 91% rename from client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts rename to client/src/app/+manage/video-channel-edit/video-channel-create.component.ts index fd00720d8..5f8e0278e 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts +++ b/client/src/app/+manage/video-channel-edit/video-channel-create.component.ts @@ -12,13 +12,13 @@ import { import { FormValidatorService } from '@app/shared/shared-forms' import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' import { HttpStatusCode, VideoChannelCreate } from '@shared/models' -import { MyVideoChannelEdit } from './my-video-channel-edit' +import { VideoChannelEdit } from './video-channel-edit' @Component({ - templateUrl: './my-video-channel-edit.component.html', - styleUrls: [ './my-video-channel-edit.component.scss' ] + templateUrl: './video-channel-edit.component.html', + styleUrls: [ './video-channel-edit.component.scss' ] }) -export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements OnInit { +export class VideoChannelCreateComponent extends VideoChannelEdit implements OnInit { error: string videoChannel = new VideoChannel({}) diff --git a/client/src/app/+manage/video-channel-edit/video-channel-edit.component.html b/client/src/app/+manage/video-channel-edit/video-channel-edit.component.html new file mode 100644 index 000000000..3751747a9 --- /dev/null +++ b/client/src/app/+manage/video-channel-edit/video-channel-edit.component.html @@ -0,0 +1,96 @@ +
{{ error }}
+ +
+
+ +
+
+
NEW CHANNEL
+
CHANNEL
+
+ +
+
Banner image of the channel
+ + + + + +
+ +
+ +
+ @{{ instanceHost }} +
+
+
+ {{ formErrors['name'] }} +
+
+ +
+ + +
+ {{ formErrors['display-name'] }} +
+
+ +
+ + +
+ {{ formErrors.description }} +
+
+ +
+ + + +
+ {{ formErrors.support }} +
+
+ +
+ +
+ +
+
+ +
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss b/client/src/app/+manage/video-channel-edit/video-channel-edit.component.scss similarity index 96% rename from client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss rename to client/src/app/+manage/video-channel-edit/video-channel-edit.component.scss index d8bfe71b6..d010d6277 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss +++ b/client/src/app/+manage/video-channel-edit/video-channel-edit.component.scss @@ -1,6 +1,10 @@ @use '_variables' as *; @use '_mixins' as *; +.margin-content { + padding-top: 20px; +} + label { font-weight: $font-regular; font-size: 100%; diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts b/client/src/app/+manage/video-channel-edit/video-channel-edit.ts similarity index 85% rename from client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts rename to client/src/app/+manage/video-channel-edit/video-channel-edit.ts index 33bb90f14..963b4cbbe 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts +++ b/client/src/app/+manage/video-channel-edit/video-channel-edit.ts @@ -1,7 +1,7 @@ import { FormReactive } from '@app/shared/shared-forms' import { VideoChannel } from '@app/shared/shared-main' -export abstract class MyVideoChannelEdit extends FormReactive { +export abstract class VideoChannelEdit extends FormReactive { videoChannel: VideoChannel abstract isCreation (): boolean diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts b/client/src/app/+manage/video-channel-edit/video-channel-update.component.ts similarity index 89% rename from client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts rename to client/src/app/+manage/video-channel-edit/video-channel-update.component.ts index f9521b8b5..21b6167b2 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts +++ b/client/src/app/+manage/video-channel-edit/video-channel-update.component.ts @@ -2,7 +2,7 @@ import { Subscription } from 'rxjs' import { HttpErrorResponse } from '@angular/common/http' import { Component, OnDestroy, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' -import { AuthService, Notifier, ServerService } from '@app/core' +import { AuthService, Notifier, RedirectService, ServerService } from '@app/core' import { genericUploadErrorHandler } from '@app/helpers' import { VIDEO_CHANNEL_DESCRIPTION_VALIDATOR, @@ -12,14 +12,14 @@ import { import { FormValidatorService } from '@app/shared/shared-forms' import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' import { HTMLServerConfig, VideoChannelUpdate } from '@shared/models' -import { MyVideoChannelEdit } from './my-video-channel-edit' +import { VideoChannelEdit } from './video-channel-edit' @Component({ selector: 'my-video-channel-update', - templateUrl: './my-video-channel-edit.component.html', - styleUrls: [ './my-video-channel-edit.component.scss' ] + templateUrl: './video-channel-edit.component.html', + styleUrls: [ './video-channel-edit.component.scss' ] }) -export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements OnInit, OnDestroy { +export class VideoChannelUpdateComponent extends VideoChannelEdit implements OnInit, OnDestroy { error: string videoChannel: VideoChannel @@ -34,7 +34,8 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements private router: Router, private route: ActivatedRoute, private videoChannelService: VideoChannelService, - private serverService: ServerService + private serverService: ServerService, + private redirectService: RedirectService ) { super() } @@ -50,9 +51,9 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements }) this.paramsSub = this.route.params.subscribe(routeParams => { - const videoChannelId = routeParams['videoChannelId'] + const videoChannelName = routeParams['videoChannelName'] - this.videoChannelService.getVideoChannel(videoChannelId) + this.videoChannelService.getVideoChannel(videoChannelName) .subscribe({ next: videoChannelToUpdate => { this.videoChannel = videoChannelToUpdate @@ -95,7 +96,7 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements this.notifier.success($localize`Video channel ${videoChannelUpdate.displayName} updated.`) - this.router.navigate([ '/my-library', 'video-channels' ]) + this.redirectService.redirectToPreviousRoute([ '/c', this.videoChannel.name ]) }, error: err => { diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html deleted file mode 100644 index 2910dffad..000000000 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html +++ /dev/null @@ -1,112 +0,0 @@ - - -
{{ error }}
- -
- -
-
-
NEW CHANNEL
-
CHANNEL
-
- -
-
Banner image of your channel
- - - - - -
- -
- -
- @{{ instanceHost }} -
-
-
- {{ formErrors['name'] }} -
-
- -
- - -
- {{ formErrors['display-name'] }} -
-
- -
- - -
- {{ formErrors.description }} -
-
- -
- - - -
- {{ formErrors.support }} -
-
- -
- -
- -
-
- -
-
-
- -
-
-
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts b/client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts index 6b8efad0b..b4962ed35 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts @@ -1,7 +1,5 @@ import { NgModule } from '@angular/core' import { RouterModule, Routes } from '@angular/router' -import { MyVideoChannelUpdateComponent } from './my-video-channel-update.component' -import { MyVideoChannelCreateComponent } from './my-video-channel-create.component' import { MyVideoChannelsComponent } from './my-video-channels.component' const myVideoChannelsRoutes: Routes = [ @@ -16,21 +14,11 @@ const myVideoChannelsRoutes: Routes = [ }, { path: 'create', - component: MyVideoChannelCreateComponent, - data: { - meta: { - title: $localize`Create a new video channel` - } - } + redirectTo: '/manage/create' }, { - path: 'update/:videoChannelId', - component: MyVideoChannelUpdateComponent, - data: { - meta: { - title: $localize`Update video channel` - } - } + path: 'update/:videoChannelName', + redirectTo: '/manage/update/:videoChannelName' } ] diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html index bbe583971..77947315b 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html @@ -9,7 +9,7 @@
- + Create video channel @@ -37,7 +37,7 @@
{videoChannel.videosCount, plural, =0 {No videos} =1 {1 video} other {{{ videoChannel.videosCount }} videos}}
- +
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts b/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts index c775bfdee..a17eb9f10 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts @@ -1,11 +1,8 @@ import { ChartModule } from 'primeng/chart' import { NgModule } from '@angular/core' -import { SharedActorImageEditModule } from '@app/shared/shared-actor-image-edit' import { SharedFormModule } from '@app/shared/shared-forms' import { SharedGlobalIconModule } from '@app/shared/shared-icons' import { SharedMainModule } from '@app/shared/shared-main' -import { MyVideoChannelCreateComponent } from './my-video-channel-create.component' -import { MyVideoChannelUpdateComponent } from './my-video-channel-update.component' import { MyVideoChannelsRoutingModule } from './my-video-channels-routing.module' import { MyVideoChannelsComponent } from './my-video-channels.component' import { SharedActorImageModule } from '@app/shared/shared-actor-image/shared-actor-image.module' @@ -19,14 +16,11 @@ import { SharedActorImageModule } from '@app/shared/shared-actor-image/shared-ac SharedMainModule, SharedFormModule, SharedGlobalIconModule, - SharedActorImageEditModule, SharedActorImageModule ], declarations: [ - MyVideoChannelsComponent, - MyVideoChannelCreateComponent, - MyVideoChannelUpdateComponent + MyVideoChannelsComponent ], exports: [], diff --git a/client/src/app/+video-channels/video-channels.component.html b/client/src/app/+video-channels/video-channels.component.html index aec2e373c..212e2f867 100644 --- a/client/src/app/+video-channels/video-channels.component.html +++ b/client/src/app/+video-channels/video-channels.component.html @@ -6,11 +6,11 @@
- + Manage channel - +