diff options
-rw-r--r-- | client/src/app/+admin/users/user-edit/user-edit.component.html | 11 | ||||
-rw-r--r-- | client/src/app/+admin/users/user-edit/user-edit.ts | 5 | ||||
-rw-r--r-- | client/src/app/+admin/users/user-edit/user-update.component.ts | 4 | ||||
-rw-r--r-- | server/controllers/api/users/index.ts | 1 | ||||
-rw-r--r-- | server/middlewares/validators/users.ts | 3 | ||||
-rw-r--r-- | server/tests/api/users/users.ts | 14 | ||||
-rw-r--r-- | shared/extra-utils/users/users.ts | 2 | ||||
-rw-r--r-- | shared/models/users/user-update.model.ts | 1 | ||||
-rw-r--r-- | support/doc/api/openapi.yaml | 29 |
9 files changed, 62 insertions, 8 deletions
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 78c92227f..fb34d6b22 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 | |||
@@ -174,6 +174,17 @@ | |||
174 | </div> | 174 | </div> |
175 | </div> | 175 | </div> |
176 | 176 | ||
177 | <div class="form-group" *ngIf="!isCreation() && getAuthPlugins().length !== 0"> | ||
178 | <label i18n for="pluginAuth">Auth plugin</label> | ||
179 | |||
180 | <div class="peertube-select-container"> | ||
181 | <select id="pluginAuth" formControlName="pluginAuth" class="form-control"> | ||
182 | <option [value]="null" i18n>None (local authentication)</option> | ||
183 | <option *ngFor="let authPlugin of getAuthPlugins()" [value]="authPlugin">{{ authPlugin }}</option> | ||
184 | </select> | ||
185 | </div> | ||
186 | </div> | ||
187 | |||
177 | <div class="form-group"> | 188 | <div class="form-group"> |
178 | <my-peertube-checkbox | 189 | <my-peertube-checkbox |
179 | inputName="byPassAutoBlock" formControlName="byPassAutoBlock" | 190 | inputName="byPassAutoBlock" formControlName="byPassAutoBlock" |
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 1613bb0d1..faa2f5ad8 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.ts +++ b/client/src/app/+admin/users/user-edit/user-edit.ts | |||
@@ -42,6 +42,11 @@ export abstract class UserEdit extends FormReactive implements OnInit { | |||
42 | return forAccount + forChannels | 42 | return forAccount + forChannels |
43 | } | 43 | } |
44 | 44 | ||
45 | getAuthPlugins () { | ||
46 | return this.serverConfig.plugin.registeredIdAndPassAuths.map(p => p.npmName) | ||
47 | .concat(this.serverConfig.plugin.registeredExternalAuths.map(p => p.npmName)) | ||
48 | } | ||
49 | |||
45 | isInBigView () { | 50 | isInBigView () { |
46 | return this.screenService.getWindowInnerWidth() > 1600 | 51 | return this.screenService.getWindowInnerWidth() > 1600 |
47 | } | 52 | } |
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 e16f66a2b..281c3dcef 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 | |||
@@ -53,7 +53,8 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { | |||
53 | role: USER_ROLE_VALIDATOR, | 53 | role: USER_ROLE_VALIDATOR, |
54 | videoQuota: USER_VIDEO_QUOTA_VALIDATOR, | 54 | videoQuota: USER_VIDEO_QUOTA_VALIDATOR, |
55 | videoQuotaDaily: USER_VIDEO_QUOTA_DAILY_VALIDATOR, | 55 | videoQuotaDaily: USER_VIDEO_QUOTA_DAILY_VALIDATOR, |
56 | byPassAutoBlock: null | 56 | byPassAutoBlock: null, |
57 | pluginAuth: null | ||
57 | }, defaultValues) | 58 | }, defaultValues) |
58 | 59 | ||
59 | this.paramsSub = this.route.params.subscribe(routeParams => { | 60 | this.paramsSub = this.route.params.subscribe(routeParams => { |
@@ -120,6 +121,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { | |||
120 | role: userJson.role.toString(), | 121 | role: userJson.role.toString(), |
121 | videoQuota: userJson.videoQuota, | 122 | videoQuota: userJson.videoQuota, |
122 | videoQuotaDaily: userJson.videoQuotaDaily, | 123 | videoQuotaDaily: userJson.videoQuotaDaily, |
124 | pluginAuth: userJson.pluginAuth, | ||
123 | byPassAutoBlock: userJson.adminFlags & UserAdminFlag.BYPASS_VIDEO_AUTO_BLACKLIST | 125 | byPassAutoBlock: userJson.adminFlags & UserAdminFlag.BYPASS_VIDEO_AUTO_BLACKLIST |
124 | }) | 126 | }) |
125 | } | 127 | } |
diff --git a/server/controllers/api/users/index.ts b/server/controllers/api/users/index.ts index c3190e731..5911d1a0f 100644 --- a/server/controllers/api/users/index.ts +++ b/server/controllers/api/users/index.ts | |||
@@ -327,6 +327,7 @@ async function updateUser (req: express.Request, res: express.Response) { | |||
327 | if (body.videoQuotaDaily !== undefined) userToUpdate.videoQuotaDaily = body.videoQuotaDaily | 327 | if (body.videoQuotaDaily !== undefined) userToUpdate.videoQuotaDaily = body.videoQuotaDaily |
328 | if (body.role !== undefined) userToUpdate.role = body.role | 328 | if (body.role !== undefined) userToUpdate.role = body.role |
329 | if (body.adminFlags !== undefined) userToUpdate.adminFlags = body.adminFlags | 329 | if (body.adminFlags !== undefined) userToUpdate.adminFlags = body.adminFlags |
330 | if (body.pluginAuth !== undefined) userToUpdate.pluginAuth = body.pluginAuth | ||
330 | 331 | ||
331 | const user = await userToUpdate.save() | 332 | const user = await userToUpdate.save() |
332 | 333 | ||
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 6b6e6c2df..345571e83 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts | |||
@@ -7,7 +7,7 @@ import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-code | |||
7 | import { UserRole } from '../../../shared/models/users' | 7 | import { UserRole } from '../../../shared/models/users' |
8 | import { UserRegister } from '../../../shared/models/users/user-register.model' | 8 | import { UserRegister } from '../../../shared/models/users/user-register.model' |
9 | import { isActorPreferredUsernameValid } from '../../helpers/custom-validators/activitypub/actor' | 9 | import { isActorPreferredUsernameValid } from '../../helpers/custom-validators/activitypub/actor' |
10 | import { isIdOrUUIDValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc' | 10 | import { exists, isIdOrUUIDValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc' |
11 | import { isThemeNameValid } from '../../helpers/custom-validators/plugins' | 11 | import { isThemeNameValid } from '../../helpers/custom-validators/plugins' |
12 | import { | 12 | import { |
13 | isNoInstanceConfigWarningModal, | 13 | isNoInstanceConfigWarningModal, |
@@ -201,6 +201,7 @@ const usersUpdateValidator = [ | |||
201 | body('emailVerified').optional().isBoolean().withMessage('Should have a valid email verified attribute'), | 201 | body('emailVerified').optional().isBoolean().withMessage('Should have a valid email verified attribute'), |
202 | body('videoQuota').optional().custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'), | 202 | body('videoQuota').optional().custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'), |
203 | body('videoQuotaDaily').optional().custom(isUserVideoQuotaDailyValid).withMessage('Should have a valid daily user quota'), | 203 | body('videoQuotaDaily').optional().custom(isUserVideoQuotaDailyValid).withMessage('Should have a valid daily user quota'), |
204 | body('pluginAuth').optional(), | ||
204 | body('role') | 205 | body('role') |
205 | .optional() | 206 | .optional() |
206 | .customSanitizer(toIntOrNull) | 207 | .customSanitizer(toIntOrNull) |
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts index cd928b980..62a59033f 100644 --- a/server/tests/api/users/users.ts +++ b/server/tests/api/users/users.ts | |||
@@ -716,11 +716,12 @@ describe('Test users', function () { | |||
716 | emailVerified: true, | 716 | emailVerified: true, |
717 | videoQuota: 42, | 717 | videoQuota: 42, |
718 | role: UserRole.MODERATOR, | 718 | role: UserRole.MODERATOR, |
719 | adminFlags: UserAdminFlag.NONE | 719 | adminFlags: UserAdminFlag.NONE, |
720 | pluginAuth: 'toto' | ||
720 | }) | 721 | }) |
721 | 722 | ||
722 | const res = await getUserInformation(server.url, accessToken, userId) | 723 | const res = await getUserInformation(server.url, accessToken, userId) |
723 | const user = res.body | 724 | const user = res.body as User |
724 | 725 | ||
725 | expect(user.username).to.equal('user_1') | 726 | expect(user.username).to.equal('user_1') |
726 | expect(user.email).to.equal('updated2@example.com') | 727 | expect(user.email).to.equal('updated2@example.com') |
@@ -730,6 +731,15 @@ describe('Test users', function () { | |||
730 | expect(user.roleLabel).to.equal('Moderator') | 731 | expect(user.roleLabel).to.equal('Moderator') |
731 | expect(user.id).to.be.a('number') | 732 | expect(user.id).to.be.a('number') |
732 | expect(user.adminFlags).to.equal(UserAdminFlag.NONE) | 733 | expect(user.adminFlags).to.equal(UserAdminFlag.NONE) |
734 | expect(user.pluginAuth).to.equal('toto') | ||
735 | }) | ||
736 | |||
737 | it('Should reset the auth plugin', async function () { | ||
738 | await updateUser({ url: server.url, userId, accessToken, pluginAuth: null }) | ||
739 | |||
740 | const res = await getUserInformation(server.url, accessToken, userId) | ||
741 | const user = res.body as User | ||
742 | expect(user.pluginAuth).to.be.null | ||
733 | }) | 743 | }) |
734 | 744 | ||
735 | it('Should have removed the user token', async function () { | 745 | it('Should have removed the user token', async function () { |
diff --git a/shared/extra-utils/users/users.ts b/shared/extra-utils/users/users.ts index c683dcdd1..db532dbb0 100644 --- a/shared/extra-utils/users/users.ts +++ b/shared/extra-utils/users/users.ts | |||
@@ -288,6 +288,7 @@ function updateUser (options: { | |||
288 | videoQuotaDaily?: number | 288 | videoQuotaDaily?: number |
289 | password?: string | 289 | password?: string |
290 | adminFlags?: UserAdminFlag | 290 | adminFlags?: UserAdminFlag |
291 | pluginAuth?: string | ||
291 | role?: UserRole | 292 | role?: UserRole |
292 | }) { | 293 | }) { |
293 | const path = '/api/v1/users/' + options.userId | 294 | const path = '/api/v1/users/' + options.userId |
@@ -300,6 +301,7 @@ function updateUser (options: { | |||
300 | if (options.videoQuotaDaily !== undefined && options.videoQuotaDaily !== null) toSend['videoQuotaDaily'] = options.videoQuotaDaily | 301 | if (options.videoQuotaDaily !== undefined && options.videoQuotaDaily !== null) toSend['videoQuotaDaily'] = options.videoQuotaDaily |
301 | if (options.role !== undefined && options.role !== null) toSend['role'] = options.role | 302 | if (options.role !== undefined && options.role !== null) toSend['role'] = options.role |
302 | if (options.adminFlags !== undefined && options.adminFlags !== null) toSend['adminFlags'] = options.adminFlags | 303 | if (options.adminFlags !== undefined && options.adminFlags !== null) toSend['adminFlags'] = options.adminFlags |
304 | if (options.pluginAuth !== undefined) toSend['pluginAuth'] = options.pluginAuth | ||
303 | 305 | ||
304 | return makePutBodyRequest({ | 306 | return makePutBodyRequest({ |
305 | url: options.url, | 307 | url: options.url, |
diff --git a/shared/models/users/user-update.model.ts b/shared/models/users/user-update.model.ts index fa43487ac..158738545 100644 --- a/shared/models/users/user-update.model.ts +++ b/shared/models/users/user-update.model.ts | |||
@@ -9,4 +9,5 @@ export interface UserUpdate { | |||
9 | videoQuotaDaily?: number | 9 | videoQuotaDaily?: number |
10 | role?: UserRole | 10 | role?: UserRole |
11 | adminFlags?: UserAdminFlag | 11 | adminFlags?: UserAdminFlag |
12 | pluginAuth?: string | ||
12 | } | 13 | } |
diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml index b05a113ca..49616bcaa 100644 --- a/support/doc/api/openapi.yaml +++ b/support/doc/api/openapi.yaml | |||
@@ -3898,6 +3898,13 @@ components: | |||
3898 | - 2 | 3898 | - 2 |
3899 | description: 'The user role (Admin = `0`, Moderator = `1`, User = `2`)' | 3899 | description: 'The user role (Admin = `0`, Moderator = `1`, User = `2`)' |
3900 | example: 2 | 3900 | example: 2 |
3901 | UserAdminFlags: | ||
3902 | type: integer | ||
3903 | enum: | ||
3904 | - 0 | ||
3905 | - 1 | ||
3906 | description: 'Admin flags for the user (None = `0`, Bypass video blacklist = `1`)' | ||
3907 | example: 1 | ||
3901 | 3908 | ||
3902 | VideoStateConstant: | 3909 | VideoStateConstant: |
3903 | properties: | 3910 | properties: |
@@ -5022,6 +5029,9 @@ components: | |||
5022 | type: string | 5029 | type: string |
5023 | format: email | 5030 | format: email |
5024 | description: The user email | 5031 | description: The user email |
5032 | pluginAuth: | ||
5033 | type: string | ||
5034 | description: Auth plugin to use to authenticate the user | ||
5025 | theme: | 5035 | theme: |
5026 | type: string | 5036 | type: string |
5027 | description: Theme enabled by this user | 5037 | description: Theme enabled by this user |
@@ -5099,8 +5109,13 @@ components: | |||
5099 | videoQuotaDaily: | 5109 | videoQuotaDaily: |
5100 | type: integer | 5110 | type: integer |
5101 | description: The user daily video quota | 5111 | description: The user daily video quota |
5112 | channelName: | ||
5113 | type: string | ||
5114 | description: The user default channel username | ||
5102 | role: | 5115 | role: |
5103 | $ref: '#/components/schemas/UserRole' | 5116 | $ref: '#/components/schemas/UserRole' |
5117 | adminFlags: | ||
5118 | $ref: '#/components/schemas/UserAdminFlags' | ||
5104 | required: | 5119 | required: |
5105 | - username | 5120 | - username |
5106 | - password | 5121 | - password |
@@ -5117,20 +5132,26 @@ components: | |||
5117 | type: string | 5132 | type: string |
5118 | format: email | 5133 | format: email |
5119 | description: The updated email of the user | 5134 | description: The updated email of the user |
5135 | emailVerified: | ||
5136 | type: boolean | ||
5137 | description: Set the email as verified | ||
5120 | videoQuota: | 5138 | videoQuota: |
5121 | type: integer | 5139 | type: integer |
5122 | description: The updated video quota of the user | 5140 | description: The updated video quota of the user |
5123 | videoQuotaDaily: | 5141 | videoQuotaDaily: |
5124 | type: integer | 5142 | type: integer |
5125 | description: The updated daily video quota of the user | 5143 | description: The updated daily video quota of the user |
5144 | pluginAuth: | ||
5145 | type: string | ||
5146 | nullable: true | ||
5147 | description: The auth plugin to use to authenticate the user | ||
5148 | example: 'peertube-plugin-auth-saml2' | ||
5126 | role: | 5149 | role: |
5127 | $ref: '#/components/schemas/UserRole' | 5150 | $ref: '#/components/schemas/UserRole' |
5151 | adminFlags: | ||
5152 | $ref: '#/components/schemas/UserAdminFlags' | ||
5128 | required: | 5153 | required: |
5129 | - id | 5154 | - id |
5130 | |||
5131 | - videoQuota | ||
5132 | - videoQuotaDaily | ||
5133 | - role | ||
5134 | UpdateMe: | 5155 | UpdateMe: |
5135 | properties: | 5156 | properties: |
5136 | password: | 5157 | password: |