aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-04-11 10:56:29 +0200
committerChocobozzz <me@florianbigard.com>2019-04-11 10:58:09 +0200
commit5d79474cc66383ecbfcef6366f63a34c3af21cbf (patch)
tree6b2cd85c25294ca04c94cbbcc90353d25e9cee06
parent2b3f1919fda81c2781ceeb9071d426c184e1b21c (diff)
downloadPeerTube-5d79474cc66383ecbfcef6366f63a34c3af21cbf.tar.gz
PeerTube-5d79474cc66383ecbfcef6366f63a34c3af21cbf.tar.zst
PeerTube-5d79474cc66383ecbfcef6366f63a34c3af21cbf.zip
Add debug component to help admins to fix IP issues
-rw-r--r--client/src/app/+admin/admin.component.html2
-rw-r--r--client/src/app/+admin/admin.component.ts12
-rw-r--r--client/src/app/+admin/admin.module.ts3
-rw-r--r--client/src/app/+admin/system/debug/debug.component.html19
-rw-r--r--client/src/app/+admin/system/debug/debug.component.scss6
-rw-r--r--client/src/app/+admin/system/debug/debug.component.ts31
-rw-r--r--client/src/app/+admin/system/debug/debug.service.ts25
-rw-r--r--client/src/app/+admin/system/debug/index.ts2
-rw-r--r--client/src/app/+admin/system/logs/logs.service.ts6
-rw-r--r--client/src/app/+admin/system/system.component.html6
-rw-r--r--client/src/app/+admin/system/system.component.ts16
-rw-r--r--client/src/app/+admin/system/system.routes.ts12
-rw-r--r--server/controllers/api/server/debug.ts25
-rw-r--r--server/controllers/api/server/index.ts2
-rw-r--r--server/tests/api/check-params/debug.ts78
-rw-r--r--server/tests/api/check-params/index.ts1
-rw-r--r--shared/models/server/debug.model.ts3
-rw-r--r--shared/models/server/index.ts1
-rw-r--r--shared/models/users/user-right.enum.ts2
19 files changed, 242 insertions, 10 deletions
diff --git a/client/src/app/+admin/admin.component.html b/client/src/app/+admin/admin.component.html
index 065d92509..98f45a7d1 100644
--- a/client/src/app/+admin/admin.component.html
+++ b/client/src/app/+admin/admin.component.html
@@ -16,7 +16,7 @@
16 Configuration 16 Configuration
17 </a> 17 </a>
18 18
19 <a i18n *ngIf="hasJobsRight() || hasLogsRight()" routerLink="/admin/system" routerLinkActive="active" class="title-page"> 19 <a i18n *ngIf="hasJobsRight() || hasLogsRight() || hasDebugRight()" routerLink="/admin/system" routerLinkActive="active" class="title-page">
20 System 20 System
21 </a> 21 </a>
22 </div> 22 </div>
diff --git a/client/src/app/+admin/admin.component.ts b/client/src/app/+admin/admin.component.ts
index fc775a5a4..408de4837 100644
--- a/client/src/app/+admin/admin.component.ts
+++ b/client/src/app/+admin/admin.component.ts
@@ -24,15 +24,19 @@ export class AdminComponent {
24 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) 24 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)
25 } 25 }
26 26
27 hasJobsRight () { 27 hasConfigRight () {
28 return this.auth.getUser().hasRight(UserRight.MANAGE_JOBS) 28 return this.auth.getUser().hasRight(UserRight.MANAGE_CONFIGURATION)
29 } 29 }
30 30
31 hasLogsRight () { 31 hasLogsRight () {
32 return this.auth.getUser().hasRight(UserRight.MANAGE_LOGS) 32 return this.auth.getUser().hasRight(UserRight.MANAGE_LOGS)
33 } 33 }
34 34
35 hasConfigRight () { 35 hasJobsRight () {
36 return this.auth.getUser().hasRight(UserRight.MANAGE_CONFIGURATION) 36 return this.auth.getUser().hasRight(UserRight.MANAGE_JOBS)
37 }
38
39 hasDebugRight () {
40 return this.auth.getUser().hasRight(UserRight.MANAGE_DEBUG)
37 } 41 }
38} 42}
diff --git a/client/src/app/+admin/admin.module.ts b/client/src/app/+admin/admin.module.ts
index ae0af686b..71a4dfc4a 100644
--- a/client/src/app/+admin/admin.module.ts
+++ b/client/src/app/+admin/admin.module.ts
@@ -20,6 +20,7 @@ import { RedundancyService } from '@app/+admin/follows/shared/redundancy.service
20import { InstanceAccountBlocklistComponent, InstanceServerBlocklistComponent } from '@app/+admin/moderation/instance-blocklist' 20import { InstanceAccountBlocklistComponent, InstanceServerBlocklistComponent } from '@app/+admin/moderation/instance-blocklist'
21import { JobsComponent } from '@app/+admin/system/jobs/jobs.component' 21import { JobsComponent } from '@app/+admin/system/jobs/jobs.component'
22import { JobService, LogsComponent, LogsService, SystemComponent } from '@app/+admin/system' 22import { JobService, LogsComponent, LogsService, SystemComponent } from '@app/+admin/system'
23import { DebugComponent, DebugService } from '@app/+admin/system/debug'
23 24
24@NgModule({ 25@NgModule({
25 imports: [ 26 imports: [
@@ -54,6 +55,7 @@ import { JobService, LogsComponent, LogsService, SystemComponent } from '@app/+a
54 SystemComponent, 55 SystemComponent,
55 JobsComponent, 56 JobsComponent,
56 LogsComponent, 57 LogsComponent,
58 DebugComponent,
57 59
58 ConfigComponent, 60 ConfigComponent,
59 EditCustomConfigComponent 61 EditCustomConfigComponent
@@ -68,6 +70,7 @@ import { JobService, LogsComponent, LogsService, SystemComponent } from '@app/+a
68 RedundancyService, 70 RedundancyService,
69 JobService, 71 JobService,
70 LogsService, 72 LogsService,
73 DebugService,
71 ConfigService 74 ConfigService
72 ] 75 ]
73}) 76})
diff --git a/client/src/app/+admin/system/debug/debug.component.html b/client/src/app/+admin/system/debug/debug.component.html
new file mode 100644
index 000000000..f35414b37
--- /dev/null
+++ b/client/src/app/+admin/system/debug/debug.component.html
@@ -0,0 +1,19 @@
1<div class="root">
2 <h4>IP</h4>
3
4 <p>PeerTube thinks your public IP is <strong>{{ debug?.ip }}</strong>.</p>
5
6 <p>If this is not your correct public IP, please consider fixing it because:</p>
7 <ul>
8 <li>Views may not be counted correctly (reduced compared to what they should be)</li>
9 <li>Anti brute force system could be overzealous</li>
10 <li>P2P system could not work correctly</li>
11 </ul>
12
13 <p>To fix it:<p>
14 <ul>
15 <li>Check the <code>trust_proxy</code> configuration key</li>
16 <li>If you run PeerTube using Docker, check you run the <code>reverse-proxy</code> with <code>network_mode: "host"</code>
17 (see <a href="https://github.com/Chocobozzz/PeerTube/issues/1643#issuecomment-464789666">issue 1643</a>)</li>
18 </ul>
19</div>
diff --git a/client/src/app/+admin/system/debug/debug.component.scss b/client/src/app/+admin/system/debug/debug.component.scss
new file mode 100644
index 000000000..90addd284
--- /dev/null
+++ b/client/src/app/+admin/system/debug/debug.component.scss
@@ -0,0 +1,6 @@
1@import '_variables';
2@import '_mixins';
3
4.root {
5 font-size: 14px;
6}
diff --git a/client/src/app/+admin/system/debug/debug.component.ts b/client/src/app/+admin/system/debug/debug.component.ts
new file mode 100644
index 000000000..8a77f79f7
--- /dev/null
+++ b/client/src/app/+admin/system/debug/debug.component.ts
@@ -0,0 +1,31 @@
1import { Component, OnInit } from '@angular/core'
2import { Notifier } from '@app/core'
3import { Debug } from '@shared/models/server'
4import { DebugService } from '@app/+admin/system/debug/debug.service'
5
6@Component({
7 templateUrl: './debug.component.html',
8 styleUrls: [ './debug.component.scss' ]
9})
10export class DebugComponent implements OnInit {
11 debug: Debug
12
13 constructor (
14 private debugService: DebugService,
15 private notifier: Notifier
16 ) {
17 }
18
19 ngOnInit (): void {
20 this.load()
21 }
22
23 load () {
24 this.debugService.getDebug()
25 .subscribe(
26 debug => this.debug = debug,
27
28 err => this.notifier.error(err.message)
29 )
30 }
31}
diff --git a/client/src/app/+admin/system/debug/debug.service.ts b/client/src/app/+admin/system/debug/debug.service.ts
new file mode 100644
index 000000000..6c722d177
--- /dev/null
+++ b/client/src/app/+admin/system/debug/debug.service.ts
@@ -0,0 +1,25 @@
1import { catchError } from 'rxjs/operators'
2import { HttpClient } from '@angular/common/http'
3import { Injectable } from '@angular/core'
4import { Observable } from 'rxjs'
5import { environment } from '../../../../environments/environment'
6import { RestExtractor, RestService } from '../../../shared'
7import { Debug } from '@shared/models/server'
8
9@Injectable()
10export class DebugService {
11 private static BASE_DEBUG_URL = environment.apiUrl + '/api/v1/server/debug'
12
13 constructor (
14 private authHttp: HttpClient,
15 private restService: RestService,
16 private restExtractor: RestExtractor
17 ) {}
18
19 getDebug (): Observable<Debug> {
20 return this.authHttp.get<Debug>(DebugService.BASE_DEBUG_URL)
21 .pipe(
22 catchError(err => this.restExtractor.handleError(err))
23 )
24 }
25}
diff --git a/client/src/app/+admin/system/debug/index.ts b/client/src/app/+admin/system/debug/index.ts
new file mode 100644
index 000000000..7fc7a0721
--- /dev/null
+++ b/client/src/app/+admin/system/debug/index.ts
@@ -0,0 +1,2 @@
1export * from './debug.component'
2export * from './debug.service'
diff --git a/client/src/app/+admin/system/logs/logs.service.ts b/client/src/app/+admin/system/logs/logs.service.ts
index 4db79a1fa..24b9cb6d1 100644
--- a/client/src/app/+admin/system/logs/logs.service.ts
+++ b/client/src/app/+admin/system/logs/logs.service.ts
@@ -9,7 +9,7 @@ import { LogLevel } from '@shared/models/server/log-level.type'
9 9
10@Injectable() 10@Injectable()
11export class LogsService { 11export class LogsService {
12 private static BASE_JOB_URL = environment.apiUrl + '/api/v1/server/logs' 12 private static BASE_LOG_URL = environment.apiUrl + '/api/v1/server/logs'
13 13
14 constructor ( 14 constructor (
15 private authHttp: HttpClient, 15 private authHttp: HttpClient,
@@ -17,14 +17,14 @@ export class LogsService {
17 private restExtractor: RestExtractor 17 private restExtractor: RestExtractor
18 ) {} 18 ) {}
19 19
20 getLogs (level: LogLevel, startDate: string, endDate?: string): Observable<any> { 20 getLogs (level: LogLevel, startDate: string, endDate?: string): Observable<any[]> {
21 let params = new HttpParams() 21 let params = new HttpParams()
22 params = params.append('startDate', startDate) 22 params = params.append('startDate', startDate)
23 params = params.append('level', level) 23 params = params.append('level', level)
24 24
25 if (endDate) params.append('endDate', endDate) 25 if (endDate) params.append('endDate', endDate)
26 26
27 return this.authHttp.get<any[]>(LogsService.BASE_JOB_URL, { params }) 27 return this.authHttp.get<any[]>(LogsService.BASE_LOG_URL, { params })
28 .pipe( 28 .pipe(
29 map(rows => rows.map(r => new LogRow(r))), 29 map(rows => rows.map(r => new LogRow(r))),
30 catchError(err => this.restExtractor.handleError(err)) 30 catchError(err => this.restExtractor.handleError(err))
diff --git a/client/src/app/+admin/system/system.component.html b/client/src/app/+admin/system/system.component.html
index 345a101e6..7c4278d35 100644
--- a/client/src/app/+admin/system/system.component.html
+++ b/client/src/app/+admin/system/system.component.html
@@ -2,9 +2,11 @@
2 <div i18n class="form-sub-title">System</div> 2 <div i18n class="form-sub-title">System</div>
3 3
4 <div class="admin-sub-nav"> 4 <div class="admin-sub-nav">
5 <a i18n routerLink="jobs" routerLinkActive="active">Jobs</a> 5 <a *ngIf="hasJobsRight()" i18n routerLink="jobs" routerLinkActive="active">Jobs</a>
6 6
7 <a i18n routerLink="logs" routerLinkActive="active">Logs</a> 7 <a *ngIf="hasLogsRight()" i18n routerLink="logs" routerLinkActive="active">Logs</a>
8
9 <a *ngIf="hasDebugRight()" i18n routerLink="debug" routerLinkActive="active">Debug</a>
8 </div> 10 </div>
9</div> 11</div>
10 12
diff --git a/client/src/app/+admin/system/system.component.ts b/client/src/app/+admin/system/system.component.ts
index 992d9c8af..b544c2a97 100644
--- a/client/src/app/+admin/system/system.component.ts
+++ b/client/src/app/+admin/system/system.component.ts
@@ -1,8 +1,24 @@
1import { Component } from '@angular/core' 1import { Component } from '@angular/core'
2import { UserRight } from '@shared/models'
3import { AuthService } from '@app/core'
2 4
3@Component({ 5@Component({
4 templateUrl: './system.component.html', 6 templateUrl: './system.component.html',
5 styleUrls: [ './system.component.scss' ] 7 styleUrls: [ './system.component.scss' ]
6}) 8})
7export class SystemComponent { 9export class SystemComponent {
10
11 constructor (private auth: AuthService) {}
12
13 hasLogsRight () {
14 return this.auth.getUser().hasRight(UserRight.MANAGE_LOGS)
15 }
16
17 hasJobsRight () {
18 return this.auth.getUser().hasRight(UserRight.MANAGE_JOBS)
19 }
20
21 hasDebugRight () {
22 return this.auth.getUser().hasRight(UserRight.MANAGE_DEBUG)
23 }
8} 24}
diff --git a/client/src/app/+admin/system/system.routes.ts b/client/src/app/+admin/system/system.routes.ts
index e6d45b760..2d851794d 100644
--- a/client/src/app/+admin/system/system.routes.ts
+++ b/client/src/app/+admin/system/system.routes.ts
@@ -4,6 +4,7 @@ import { UserRight } from '../../../../../shared'
4import { JobsComponent } from '@app/+admin/system/jobs/jobs.component' 4import { JobsComponent } from '@app/+admin/system/jobs/jobs.component'
5import { LogsComponent } from '@app/+admin/system/logs' 5import { LogsComponent } from '@app/+admin/system/logs'
6import { SystemComponent } from '@app/+admin/system/system.component' 6import { SystemComponent } from '@app/+admin/system/system.component'
7import { DebugComponent } from '@app/+admin/system/debug'
7 8
8export const SystemRoutes: Routes = [ 9export const SystemRoutes: Routes = [
9 { 10 {
@@ -38,6 +39,17 @@ export const SystemRoutes: Routes = [
38 title: 'Logs' 39 title: 'Logs'
39 } 40 }
40 } 41 }
42 },
43 {
44 path: 'debug',
45 canActivate: [ UserRightGuard ],
46 component: DebugComponent,
47 data: {
48 meta: {
49 userRight: UserRight.MANAGE_DEBUG,
50 title: 'Debug'
51 }
52 }
41 } 53 }
42 ] 54 ]
43 } 55 }
diff --git a/server/controllers/api/server/debug.ts b/server/controllers/api/server/debug.ts
new file mode 100644
index 000000000..4450038f6
--- /dev/null
+++ b/server/controllers/api/server/debug.ts
@@ -0,0 +1,25 @@
1import * as express from 'express'
2import { UserRight } from '../../../../shared/models/users'
3import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares'
4
5const debugRouter = express.Router()
6
7debugRouter.get('/debug',
8 authenticate,
9 ensureUserHasRight(UserRight.MANAGE_DEBUG),
10 asyncMiddleware(getDebug)
11)
12
13// ---------------------------------------------------------------------------
14
15export {
16 debugRouter
17}
18
19// ---------------------------------------------------------------------------
20
21async function getDebug (req: express.Request, res: express.Response) {
22 return res.json({
23 ip: req.ip
24 }).end()
25}
diff --git a/server/controllers/api/server/index.ts b/server/controllers/api/server/index.ts
index de09588df..6b8793a19 100644
--- a/server/controllers/api/server/index.ts
+++ b/server/controllers/api/server/index.ts
@@ -5,6 +5,7 @@ import { serverRedundancyRouter } from './redundancy'
5import { serverBlocklistRouter } from './server-blocklist' 5import { serverBlocklistRouter } from './server-blocklist'
6import { contactRouter } from './contact' 6import { contactRouter } from './contact'
7import { logsRouter } from './logs' 7import { logsRouter } from './logs'
8import { debugRouter } from './debug'
8 9
9const serverRouter = express.Router() 10const serverRouter = express.Router()
10 11
@@ -14,6 +15,7 @@ serverRouter.use('/', statsRouter)
14serverRouter.use('/', serverBlocklistRouter) 15serverRouter.use('/', serverBlocklistRouter)
15serverRouter.use('/', contactRouter) 16serverRouter.use('/', contactRouter)
16serverRouter.use('/', logsRouter) 17serverRouter.use('/', logsRouter)
18serverRouter.use('/', debugRouter)
17 19
18// --------------------------------------------------------------------------- 20// ---------------------------------------------------------------------------
19 21
diff --git a/server/tests/api/check-params/debug.ts b/server/tests/api/check-params/debug.ts
new file mode 100644
index 000000000..9bf664657
--- /dev/null
+++ b/server/tests/api/check-params/debug.ts
@@ -0,0 +1,78 @@
1/* tslint:disable:no-unused-expression */
2
3import 'mocha'
4
5import {
6 createUser,
7 flushTests,
8 killallServers,
9 runServer,
10 ServerInfo,
11 setAccessTokensToServers,
12 userLogin
13} from '../../../../shared/utils'
14import { makeGetRequest } from '../../../../shared/utils/requests/requests'
15
16describe('Test debug API validators', function () {
17 const path = '/api/v1/server/debug'
18 let server: ServerInfo
19 let userAccessToken = ''
20
21 // ---------------------------------------------------------------
22
23 before(async function () {
24 this.timeout(120000)
25
26 await flushTests()
27
28 server = await runServer(1)
29
30 await setAccessTokensToServers([ server ])
31
32 const user = {
33 username: 'user1',
34 password: 'my super password'
35 }
36 await createUser(server.url, server.accessToken, user.username, user.password)
37 userAccessToken = await userLogin(server, user)
38 })
39
40 describe('When getting debug endpoint', function () {
41
42 it('Should fail with a non authenticated user', async function () {
43 await makeGetRequest({
44 url: server.url,
45 path,
46 statusCodeExpected: 401
47 })
48 })
49
50 it('Should fail with a non admin user', async function () {
51 await makeGetRequest({
52 url: server.url,
53 path,
54 token: userAccessToken,
55 statusCodeExpected: 403
56 })
57 })
58
59 it('Should succeed with the correct params', async function () {
60 await makeGetRequest({
61 url: server.url,
62 path,
63 token: server.accessToken,
64 query: { startDate: new Date().toISOString() },
65 statusCodeExpected: 200
66 })
67 })
68 })
69
70 after(async function () {
71 killallServers([ server ])
72
73 // Keep the logs if the test failed
74 if (this['ok']) {
75 await flushTests()
76 }
77 })
78})
diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts
index bdac95025..844fa31c5 100644
--- a/server/tests/api/check-params/index.ts
+++ b/server/tests/api/check-params/index.ts
@@ -2,6 +2,7 @@ import './accounts'
2import './blocklist' 2import './blocklist'
3import './config' 3import './config'
4import './contact-form' 4import './contact-form'
5import './debug'
5import './follows' 6import './follows'
6import './jobs' 7import './jobs'
7import './logs' 8import './logs'
diff --git a/shared/models/server/debug.model.ts b/shared/models/server/debug.model.ts
new file mode 100644
index 000000000..61cba6518
--- /dev/null
+++ b/shared/models/server/debug.model.ts
@@ -0,0 +1,3 @@
1export interface Debug {
2 ip: string
3}
diff --git a/shared/models/server/index.ts b/shared/models/server/index.ts
index c42f6f67f..bf61ab270 100644
--- a/shared/models/server/index.ts
+++ b/shared/models/server/index.ts
@@ -1,6 +1,7 @@
1export * from './about.model' 1export * from './about.model'
2export * from './contact-form.model' 2export * from './contact-form.model'
3export * from './custom-config.model' 3export * from './custom-config.model'
4export * from './debug.model'
4export * from './job.model' 5export * from './job.model'
5export * from './server-config.model' 6export * from './server-config.model'
6export * from './server-stats.model' 7export * from './server-stats.model'
diff --git a/shared/models/users/user-right.enum.ts b/shared/models/users/user-right.enum.ts
index 5ec255ea5..71701bdb4 100644
--- a/shared/models/users/user-right.enum.ts
+++ b/shared/models/users/user-right.enum.ts
@@ -7,6 +7,8 @@ export enum UserRight {
7 7
8 MANAGE_LOGS, 8 MANAGE_LOGS,
9 9
10 MANAGE_DEBUG,
11
10 MANAGE_SERVER_REDUNDANCY, 12 MANAGE_SERVER_REDUNDANCY,
11 13
12 MANAGE_VIDEO_ABUSES, 14 MANAGE_VIDEO_ABUSES,