diff options
Diffstat (limited to 'client/src/app')
7 files changed, 46 insertions, 14 deletions
diff --git a/client/src/app/+admin/users/user-edit/user-create.component.ts b/client/src/app/+admin/users/user-edit/user-create.component.ts index 9a6801806..3b57a49c6 100644 --- a/client/src/app/+admin/users/user-edit/user-create.component.ts +++ b/client/src/app/+admin/users/user-edit/user-create.component.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | 1 | import { Component, OnInit } from '@angular/core' |
2 | import { Router } from '@angular/router' | 2 | import { Router } from '@angular/router' |
3 | import { Notifier, ServerService } from '@app/core' | 3 | import { AuthService, Notifier, ServerService } from '@app/core' |
4 | import { UserCreate, UserRole } from '../../../../../../shared' | 4 | import { UserCreate, UserRole } from '../../../../../../shared' |
5 | import { UserEdit } from './user-edit' | 5 | import { UserEdit } from './user-edit' |
6 | import { I18n } from '@ngx-translate/i18n-polyfill' | 6 | import { I18n } from '@ngx-translate/i18n-polyfill' |
@@ -8,7 +8,6 @@ import { FormValidatorService } from '@app/shared/forms/form-validators/form-val | |||
8 | import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service' | 8 | import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service' |
9 | import { ConfigService } from '@app/+admin/config/shared/config.service' | 9 | import { ConfigService } from '@app/+admin/config/shared/config.service' |
10 | import { UserService } from '@app/shared' | 10 | import { UserService } from '@app/shared' |
11 | import { UserAdminFlag } from '@shared/models/users/user-flag.model' | ||
12 | 11 | ||
13 | @Component({ | 12 | @Component({ |
14 | selector: 'my-user-create', | 13 | selector: 'my-user-create', |
@@ -22,6 +21,7 @@ export class UserCreateComponent extends UserEdit implements OnInit { | |||
22 | protected serverService: ServerService, | 21 | protected serverService: ServerService, |
23 | protected formValidatorService: FormValidatorService, | 22 | protected formValidatorService: FormValidatorService, |
24 | protected configService: ConfigService, | 23 | protected configService: ConfigService, |
24 | protected auth: AuthService, | ||
25 | private userValidatorsService: UserValidatorsService, | 25 | private userValidatorsService: UserValidatorsService, |
26 | private router: Router, | 26 | private router: Router, |
27 | private notifier: Notifier, | 27 | private notifier: Notifier, |
diff --git a/client/src/app/+admin/users/user-edit/user-edit.component.html b/client/src/app/+admin/users/user-edit/user-edit.component.html index 400bac5d4..cb0f36f05 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.component.html +++ b/client/src/app/+admin/users/user-edit/user-edit.component.html | |||
@@ -41,7 +41,7 @@ | |||
41 | <label i18n for="role">Role</label> | 41 | <label i18n for="role">Role</label> |
42 | <div class="peertube-select-container"> | 42 | <div class="peertube-select-container"> |
43 | <select id="role" formControlName="role"> | 43 | <select id="role" formControlName="role"> |
44 | <option *ngFor="let role of roles" [value]="role.value"> | 44 | <option *ngFor="let role of getRoles()" [value]="role.value"> |
45 | {{ role.label }} | 45 | {{ role.label }} |
46 | </option> | 46 | </option> |
47 | </select> | 47 | </select> |
diff --git a/client/src/app/+admin/users/user-edit/user-edit.ts b/client/src/app/+admin/users/user-edit/user-edit.ts index ee6d2c489..6625d65d6 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.ts +++ b/client/src/app/+admin/users/user-edit/user-edit.ts | |||
@@ -1,22 +1,34 @@ | |||
1 | import { ServerService } from '../../../core' | 1 | import { AuthService, ServerService } from '../../../core' |
2 | import { FormReactive } from '../../../shared' | 2 | import { FormReactive } from '../../../shared' |
3 | import { USER_ROLE_LABELS, VideoResolution } from '../../../../../../shared' | 3 | import { USER_ROLE_LABELS, UserRole, VideoResolution } from '../../../../../../shared' |
4 | import { ConfigService } from '@app/+admin/config/shared/config.service' | 4 | import { ConfigService } from '@app/+admin/config/shared/config.service' |
5 | import { UserAdminFlag } from '@shared/models/users/user-flag.model' | 5 | import { UserAdminFlag } from '@shared/models/users/user-flag.model' |
6 | 6 | ||
7 | export abstract class UserEdit extends FormReactive { | 7 | export abstract class UserEdit extends FormReactive { |
8 | videoQuotaOptions: { value: string, label: string }[] = [] | 8 | videoQuotaOptions: { value: string, label: string }[] = [] |
9 | videoQuotaDailyOptions: { value: string, label: string }[] = [] | 9 | videoQuotaDailyOptions: { value: string, label: string }[] = [] |
10 | roles = Object.keys(USER_ROLE_LABELS) | ||
11 | .map(key => ({ value: key.toString(), label: USER_ROLE_LABELS[key] })) | ||
12 | username: string | 10 | username: string |
13 | userId: number | 11 | userId: number |
14 | 12 | ||
15 | protected abstract serverService: ServerService | 13 | protected abstract serverService: ServerService |
16 | protected abstract configService: ConfigService | 14 | protected abstract configService: ConfigService |
15 | protected abstract auth: AuthService | ||
17 | abstract isCreation (): boolean | 16 | abstract isCreation (): boolean |
18 | abstract getFormButtonTitle (): string | 17 | abstract getFormButtonTitle (): string |
19 | 18 | ||
19 | getRoles () { | ||
20 | const authUser = this.auth.getUser() | ||
21 | |||
22 | if (authUser.role === UserRole.ADMINISTRATOR) { | ||
23 | return Object.keys(USER_ROLE_LABELS) | ||
24 | .map(key => ({ value: key.toString(), label: USER_ROLE_LABELS[key] })) | ||
25 | } | ||
26 | |||
27 | return [ | ||
28 | { value: UserRole.USER.toString(), label: USER_ROLE_LABELS[UserRole.USER] } | ||
29 | ] | ||
30 | } | ||
31 | |||
20 | isTranscodingInformationDisplayed () { | 32 | isTranscodingInformationDisplayed () { |
21 | const formVideoQuota = parseInt(this.form.value['videoQuota'], 10) | 33 | const formVideoQuota = parseInt(this.form.value['videoQuota'], 10) |
22 | 34 | ||
diff --git a/client/src/app/+admin/users/user-edit/user-update.component.ts b/client/src/app/+admin/users/user-edit/user-update.component.ts index 04b2935f4..c7052a925 100644 --- a/client/src/app/+admin/users/user-edit/user-update.component.ts +++ b/client/src/app/+admin/users/user-edit/user-update.component.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { Component, OnDestroy, OnInit } from '@angular/core' | 1 | import { Component, OnDestroy, OnInit } from '@angular/core' |
2 | import { ActivatedRoute, Router } from '@angular/router' | 2 | import { ActivatedRoute, Router } from '@angular/router' |
3 | import { Subscription } from 'rxjs' | 3 | import { Subscription } from 'rxjs' |
4 | import { Notifier } from '@app/core' | 4 | import { AuthService, Notifier } from '@app/core' |
5 | import { ServerService } from '../../../core' | 5 | import { ServerService } from '../../../core' |
6 | import { UserEdit } from './user-edit' | 6 | import { UserEdit } from './user-edit' |
7 | import { User, UserUpdate } from '../../../../../../shared' | 7 | import { User, UserUpdate } from '../../../../../../shared' |
@@ -29,6 +29,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { | |||
29 | protected formValidatorService: FormValidatorService, | 29 | protected formValidatorService: FormValidatorService, |
30 | protected serverService: ServerService, | 30 | protected serverService: ServerService, |
31 | protected configService: ConfigService, | 31 | protected configService: ConfigService, |
32 | protected auth: AuthService, | ||
32 | private userValidatorsService: UserValidatorsService, | 33 | private userValidatorsService: UserValidatorsService, |
33 | private route: ActivatedRoute, | 34 | private route: ActivatedRoute, |
34 | private router: Router, | 35 | private router: Router, |
diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts index c9c790689..ab82713b2 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.ts +++ b/client/src/app/+admin/users/user-list/user-list.component.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { Component, OnInit, ViewChild } from '@angular/core' | 1 | import { Component, OnInit, ViewChild } from '@angular/core' |
2 | import { Notifier } from '@app/core' | 2 | import { AuthService, Notifier } from '@app/core' |
3 | import { SortMeta } from 'primeng/components/common/sortmeta' | 3 | import { SortMeta } from 'primeng/components/common/sortmeta' |
4 | import { ConfirmService, ServerService } from '../../../core' | 4 | import { ConfirmService, ServerService } from '../../../core' |
5 | import { RestPagination, RestTable, UserService } from '../../../shared' | 5 | import { RestPagination, RestTable, UserService } from '../../../shared' |
@@ -30,11 +30,16 @@ export class UserListComponent extends RestTable implements OnInit { | |||
30 | private confirmService: ConfirmService, | 30 | private confirmService: ConfirmService, |
31 | private serverService: ServerService, | 31 | private serverService: ServerService, |
32 | private userService: UserService, | 32 | private userService: UserService, |
33 | private auth: AuthService, | ||
33 | private i18n: I18n | 34 | private i18n: I18n |
34 | ) { | 35 | ) { |
35 | super() | 36 | super() |
36 | } | 37 | } |
37 | 38 | ||
39 | get authUser () { | ||
40 | return this.auth.getUser() | ||
41 | } | ||
42 | |||
38 | get requiresEmailVerification () { | 43 | get requiresEmailVerification () { |
39 | return this.serverService.getConfig().signup.requiresEmailVerification | 44 | return this.serverService.getConfig().signup.requiresEmailVerification |
40 | } | 45 | } |
@@ -45,22 +50,26 @@ export class UserListComponent extends RestTable implements OnInit { | |||
45 | this.bulkUserActions = [ | 50 | this.bulkUserActions = [ |
46 | { | 51 | { |
47 | label: this.i18n('Delete'), | 52 | label: this.i18n('Delete'), |
48 | handler: users => this.removeUsers(users) | 53 | handler: users => this.removeUsers(users), |
54 | isDisplayed: users => users.every(u => this.authUser.canManage(u)) | ||
49 | }, | 55 | }, |
50 | { | 56 | { |
51 | label: this.i18n('Ban'), | 57 | label: this.i18n('Ban'), |
52 | handler: users => this.openBanUserModal(users), | 58 | handler: users => this.openBanUserModal(users), |
53 | isDisplayed: users => users.every(u => u.blocked === false) | 59 | isDisplayed: users => users.every(u => this.authUser.canManage(u) && u.blocked === false) |
54 | }, | 60 | }, |
55 | { | 61 | { |
56 | label: this.i18n('Unban'), | 62 | label: this.i18n('Unban'), |
57 | handler: users => this.unbanUsers(users), | 63 | handler: users => this.unbanUsers(users), |
58 | isDisplayed: users => users.every(u => u.blocked === true) | 64 | isDisplayed: users => users.every(u => this.authUser.canManage(u) && u.blocked === true) |
59 | }, | 65 | }, |
60 | { | 66 | { |
61 | label: this.i18n('Set Email as Verified'), | 67 | label: this.i18n('Set Email as Verified'), |
62 | handler: users => this.setEmailsAsVerified(users), | 68 | handler: users => this.setEmailsAsVerified(users), |
63 | isDisplayed: users => this.requiresEmailVerification && users.every(u => !u.blocked && u.emailVerified === false) | 69 | isDisplayed: users => { |
70 | return this.requiresEmailVerification && | ||
71 | users.every(u => this.authUser.canManage(u) && !u.blocked && u.emailVerified === false) | ||
72 | } | ||
64 | } | 73 | } |
65 | ] | 74 | ] |
66 | } | 75 | } |
diff --git a/client/src/app/core/auth/auth-user.model.ts b/client/src/app/core/auth/auth-user.model.ts index abb11fdc2..334ede0cd 100644 --- a/client/src/app/core/auth/auth-user.model.ts +++ b/client/src/app/core/auth/auth-user.model.ts | |||
@@ -139,6 +139,15 @@ export class AuthUser extends User { | |||
139 | return hasUserRight(this.role, right) | 139 | return hasUserRight(this.role, right) |
140 | } | 140 | } |
141 | 141 | ||
142 | canManage (user: ServerUserModel) { | ||
143 | const myRole = this.role | ||
144 | |||
145 | if (myRole === UserRole.ADMINISTRATOR) return true | ||
146 | |||
147 | // I'm a moderator: I can only manage users | ||
148 | return user.role === UserRole.USER | ||
149 | } | ||
150 | |||
142 | save () { | 151 | save () { |
143 | peertubeLocalStorage.setItem(AuthUser.KEYS.ID, this.id.toString()) | 152 | peertubeLocalStorage.setItem(AuthUser.KEYS.ID, this.id.toString()) |
144 | peertubeLocalStorage.setItem(AuthUser.KEYS.USERNAME, this.username) | 153 | peertubeLocalStorage.setItem(AuthUser.KEYS.USERNAME, this.username) |
diff --git a/client/src/app/shared/moderation/user-moderation-dropdown.component.ts b/client/src/app/shared/moderation/user-moderation-dropdown.component.ts index 24f717821..e9d4c1437 100644 --- a/client/src/app/shared/moderation/user-moderation-dropdown.component.ts +++ b/client/src/app/shared/moderation/user-moderation-dropdown.component.ts | |||
@@ -33,6 +33,7 @@ export class UserModerationDropdownComponent implements OnChanges { | |||
33 | private serverService: ServerService, | 33 | private serverService: ServerService, |
34 | private userService: UserService, | 34 | private userService: UserService, |
35 | private blocklistService: BlocklistService, | 35 | private blocklistService: BlocklistService, |
36 | private auth: AuthService, | ||
36 | private i18n: I18n | 37 | private i18n: I18n |
37 | ) { } | 38 | ) { } |
38 | 39 | ||
@@ -230,7 +231,7 @@ export class UserModerationDropdownComponent implements OnChanges { | |||
230 | 231 | ||
231 | if (this.user && authUser.id === this.user.id) return | 232 | if (this.user && authUser.id === this.user.id) return |
232 | 233 | ||
233 | if (this.user && authUser.hasRight(UserRight.MANAGE_USERS)) { | 234 | if (this.user && authUser.hasRight(UserRight.MANAGE_USERS) && authUser.canManage(this.user)) { |
234 | this.userActions.push([ | 235 | this.userActions.push([ |
235 | { | 236 | { |
236 | label: this.i18n('Edit'), | 237 | label: this.i18n('Edit'), |