aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/core
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/core')
-rw-r--r--client/src/app/core/auth/auth-user.model.ts11
-rw-r--r--client/src/app/core/auth/auth.service.ts8
-rw-r--r--client/src/app/core/auth/index.ts2
-rw-r--r--client/src/app/core/core.module.ts6
-rw-r--r--client/src/app/core/menu/menu-admin.component.html10
-rw-r--r--client/src/app/core/menu/menu-admin.component.ts27
-rw-r--r--client/src/app/core/menu/menu.component.html4
-rw-r--r--client/src/app/core/menu/menu.component.ts46
-rw-r--r--client/src/app/core/routing/index.ts2
-rw-r--r--client/src/app/core/routing/login-guard.service.ts (renamed from client/src/app/core/auth/login-guard.service.ts)2
-rw-r--r--client/src/app/core/routing/user-right-guard.service.ts35
11 files changed, 129 insertions, 24 deletions
diff --git a/client/src/app/core/auth/auth-user.model.ts b/client/src/app/core/auth/auth-user.model.ts
index 81bff99a0..085b763ec 100644
--- a/client/src/app/core/auth/auth-user.model.ts
+++ b/client/src/app/core/auth/auth-user.model.ts
@@ -1,6 +1,7 @@
1// Do not use the barrel (dependency loop) 1// Do not use the barrel (dependency loop)
2import { UserRole } from '../../../../../shared/models/users/user-role.type' 2import { hasUserRight, UserRole } from '../../../../../shared/models/users/user-role'
3import { User, UserConstructorHash } from '../../shared/users/user.model' 3import { User, UserConstructorHash } from '../../shared/users/user.model'
4import { UserRight } from '../../../../../shared/models/users/user-right.enum'
4 5
5export type TokenOptions = { 6export type TokenOptions = {
6 accessToken: string 7 accessToken: string
@@ -81,7 +82,7 @@ export class AuthUser extends User {
81 id: parseInt(localStorage.getItem(this.KEYS.ID), 10), 82 id: parseInt(localStorage.getItem(this.KEYS.ID), 10),
82 username: localStorage.getItem(this.KEYS.USERNAME), 83 username: localStorage.getItem(this.KEYS.USERNAME),
83 email: localStorage.getItem(this.KEYS.EMAIL), 84 email: localStorage.getItem(this.KEYS.EMAIL),
84 role: localStorage.getItem(this.KEYS.ROLE) as UserRole, 85 role: parseInt(localStorage.getItem(this.KEYS.ROLE), 10) as UserRole,
85 displayNSFW: localStorage.getItem(this.KEYS.DISPLAY_NSFW) === 'true' 86 displayNSFW: localStorage.getItem(this.KEYS.DISPLAY_NSFW) === 'true'
86 }, 87 },
87 Tokens.load() 88 Tokens.load()
@@ -122,11 +123,15 @@ export class AuthUser extends User {
122 this.tokens.refreshToken = refreshToken 123 this.tokens.refreshToken = refreshToken
123 } 124 }
124 125
126 hasRight(right: UserRight) {
127 return hasUserRight(this.role, right)
128 }
129
125 save () { 130 save () {
126 localStorage.setItem(AuthUser.KEYS.ID, this.id.toString()) 131 localStorage.setItem(AuthUser.KEYS.ID, this.id.toString())
127 localStorage.setItem(AuthUser.KEYS.USERNAME, this.username) 132 localStorage.setItem(AuthUser.KEYS.USERNAME, this.username)
128 localStorage.setItem(AuthUser.KEYS.EMAIL, this.email) 133 localStorage.setItem(AuthUser.KEYS.EMAIL, this.email)
129 localStorage.setItem(AuthUser.KEYS.ROLE, this.role) 134 localStorage.setItem(AuthUser.KEYS.ROLE, this.role.toString())
130 localStorage.setItem(AuthUser.KEYS.DISPLAY_NSFW, JSON.stringify(this.displayNSFW)) 135 localStorage.setItem(AuthUser.KEYS.DISPLAY_NSFW, JSON.stringify(this.displayNSFW))
131 this.tokens.save() 136 this.tokens.save()
132 } 137 }
diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts
index 9ac9ba7bb..df6e5135b 100644
--- a/client/src/app/core/auth/auth.service.ts
+++ b/client/src/app/core/auth/auth.service.ts
@@ -21,7 +21,7 @@ import {
21// Do not use the barrel (dependency loop) 21// Do not use the barrel (dependency loop)
22import { RestExtractor } from '../../shared/rest' 22import { RestExtractor } from '../../shared/rest'
23import { UserLogin } from '../../../../../shared/models/users/user-login.model' 23import { UserLogin } from '../../../../../shared/models/users/user-login.model'
24import { User, UserConstructorHash } from '../../shared/users/user.model' 24import { UserConstructorHash } from '../../shared/users/user.model'
25 25
26interface UserLoginWithUsername extends UserLogin { 26interface UserLoginWithUsername extends UserLogin {
27 access_token: string 27 access_token: string
@@ -126,12 +126,6 @@ export class AuthService {
126 return this.user 126 return this.user
127 } 127 }
128 128
129 isAdmin () {
130 if (this.user === null) return false
131
132 return this.user.isAdmin()
133 }
134
135 isLoggedIn () { 129 isLoggedIn () {
136 return !!this.getAccessToken() 130 return !!this.getAccessToken()
137 } 131 }
diff --git a/client/src/app/core/auth/index.ts b/client/src/app/core/auth/index.ts
index a81f2c002..bc7bfec0e 100644
--- a/client/src/app/core/auth/index.ts
+++ b/client/src/app/core/auth/index.ts
@@ -1,4 +1,4 @@
1export * from './auth-status.model' 1export * from './auth-status.model'
2export * from './auth-user.model' 2export * from './auth-user.model'
3export * from './auth.service' 3export * from './auth.service'
4export * from './login-guard.service' 4export * from '../routing/login-guard.service'
diff --git a/client/src/app/core/core.module.ts b/client/src/app/core/core.module.ts
index 163a6bbde..90e2cb190 100644
--- a/client/src/app/core/core.module.ts
+++ b/client/src/app/core/core.module.ts
@@ -7,7 +7,8 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
7import { SimpleNotificationsModule } from 'angular2-notifications' 7import { SimpleNotificationsModule } from 'angular2-notifications'
8import { ModalModule } from 'ngx-bootstrap/modal' 8import { ModalModule } from 'ngx-bootstrap/modal'
9 9
10import { AuthService, LoginGuard } from './auth' 10import { AuthService } from './auth'
11import { LoginGuard, UserRightGuard } from './routing'
11import { ServerService } from './server' 12import { ServerService } from './server'
12import { ConfirmComponent, ConfirmService } from './confirm' 13import { ConfirmComponent, ConfirmService } from './confirm'
13import { MenuComponent, MenuAdminComponent } from './menu' 14import { MenuComponent, MenuAdminComponent } from './menu'
@@ -42,7 +43,8 @@ import { throwIfAlreadyLoaded } from './module-import-guard'
42 AuthService, 43 AuthService,
43 ConfirmService, 44 ConfirmService,
44 ServerService, 45 ServerService,
45 LoginGuard 46 LoginGuard,
47 UserRightGuard
46 ] 48 ]
47}) 49})
48export class CoreModule { 50export class CoreModule {
diff --git a/client/src/app/core/menu/menu-admin.component.html b/client/src/app/core/menu/menu-admin.component.html
index edacdee6d..c2b2958b4 100644
--- a/client/src/app/core/menu/menu-admin.component.html
+++ b/client/src/app/core/menu/menu-admin.component.html
@@ -1,26 +1,26 @@
1<menu> 1<menu>
2 <div class="panel-block"> 2 <div class="panel-block">
3 <a routerLink="/admin/users/list" routerLinkActive="active"> 3 <a *ngIf="hasUsersRight()" routerLink="/admin/users" routerLinkActive="active">
4 <span class="hidden-xs glyphicon glyphicon-user"></span> 4 <span class="hidden-xs glyphicon glyphicon-user"></span>
5 List users 5 List users
6 </a> 6 </a>
7 7
8 <a routerLink="/admin/friends/list" routerLinkActive="active"> 8 <a *ngIf="hasFriendsRight()" routerLink="/admin/friends" routerLinkActive="active">
9 <span class="hidden-xs glyphicon glyphicon-cloud"></span> 9 <span class="hidden-xs glyphicon glyphicon-cloud"></span>
10 List friends 10 List friends
11 </a> 11 </a>
12 12
13 <a routerLink="/admin/requests/stats" routerLinkActive="active"> 13 <a *ngIf="hasRequestsStatRight()" routerLink="/admin/requests/stats" routerLinkActive="active">
14 <span class="hidden-xs glyphicon glyphicon-stats"></span> 14 <span class="hidden-xs glyphicon glyphicon-stats"></span>
15 Request stats 15 Request stats
16 </a> 16 </a>
17 17
18 <a routerLink="/admin/video-abuses/list" routerLinkActive="active"> 18 <a *ngIf="hasVideoAbusesRight()" routerLink="/admin/video-abuses" routerLinkActive="active">
19 <span class="hidden-xs glyphicon glyphicon-alert"></span> 19 <span class="hidden-xs glyphicon glyphicon-alert"></span>
20 Video abuses 20 Video abuses
21 </a> 21 </a>
22 22
23 <a routerLink="/admin/video-blacklist/list" routerLinkActive="active"> 23 <a *ngIf="hasVideoBlacklistRight()" routerLink="/admin/video-blacklist" routerLinkActive="active">
24 <span class="hidden-xs glyphicon glyphicon-eye-close"></span> 24 <span class="hidden-xs glyphicon glyphicon-eye-close"></span>
25 Video blacklist 25 Video blacklist
26 </a> 26 </a>
diff --git a/client/src/app/core/menu/menu-admin.component.ts b/client/src/app/core/menu/menu-admin.component.ts
index f6cc6554c..074f1dbaf 100644
--- a/client/src/app/core/menu/menu-admin.component.ts
+++ b/client/src/app/core/menu/menu-admin.component.ts
@@ -1,8 +1,33 @@
1import { Component } from '@angular/core' 1import { Component } from '@angular/core'
2 2
3import { AuthService } from '../auth/auth.service'
4import { UserRight } from '../../../../../shared'
5
3@Component({ 6@Component({
4 selector: 'my-menu-admin', 7 selector: 'my-menu-admin',
5 templateUrl: './menu-admin.component.html', 8 templateUrl: './menu-admin.component.html',
6 styleUrls: [ './menu.component.scss' ] 9 styleUrls: [ './menu.component.scss' ]
7}) 10})
8export class MenuAdminComponent { } 11export class MenuAdminComponent {
12 constructor (private auth: AuthService) {}
13
14 hasUsersRight () {
15 return this.auth.getUser().hasRight(UserRight.MANAGE_USERS)
16 }
17
18 hasFriendsRight () {
19 return this.auth.getUser().hasRight(UserRight.MANAGE_PODS)
20 }
21
22 hasRequestsStatRight () {
23 return this.auth.getUser().hasRight(UserRight.MANAGE_REQUEST_SCHEDULERS)
24 }
25
26 hasVideoAbusesRight () {
27 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_ABUSES)
28 }
29
30 hasVideoBlacklistRight () {
31 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)
32 }
33}
diff --git a/client/src/app/core/menu/menu.component.html b/client/src/app/core/menu/menu.component.html
index ca341a0fd..2d8aace54 100644
--- a/client/src/app/core/menu/menu.component.html
+++ b/client/src/app/core/menu/menu.component.html
@@ -39,10 +39,10 @@
39 </a> 39 </a>
40 </div> 40 </div>
41 41
42 <div *ngIf="isUserAdmin()" class="panel-block"> 42 <div *ngIf="userHasAdminAccess" class="panel-block">
43 <div class="block-title">Other</div> 43 <div class="block-title">Other</div>
44 44
45 <a routerLink="/admin" routerLinkActive="active"> 45 <a [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active">
46 <span class="hidden-xs glyphicon glyphicon-cog"></span> 46 <span class="hidden-xs glyphicon glyphicon-cog"></span>
47 Administration 47 Administration
48 </a> 48 </a>
diff --git a/client/src/app/core/menu/menu.component.ts b/client/src/app/core/menu/menu.component.ts
index 8f15d8838..c66a5eccc 100644
--- a/client/src/app/core/menu/menu.component.ts
+++ b/client/src/app/core/menu/menu.component.ts
@@ -3,6 +3,7 @@ import { Router } from '@angular/router'
3 3
4import { AuthService, AuthStatus } from '../auth' 4import { AuthService, AuthStatus } from '../auth'
5import { ServerService } from '../server' 5import { ServerService } from '../server'
6import { UserRight } from '../../../../../shared/models/users/user-right.enum'
6 7
7@Component({ 8@Component({
8 selector: 'my-menu', 9 selector: 'my-menu',
@@ -11,6 +12,15 @@ import { ServerService } from '../server'
11}) 12})
12export class MenuComponent implements OnInit { 13export class MenuComponent implements OnInit {
13 isLoggedIn: boolean 14 isLoggedIn: boolean
15 userHasAdminAccess = false
16
17 private routesPerRight = {
18 [UserRight.MANAGE_USERS]: '/admin/users',
19 [UserRight.MANAGE_PODS]: '/admin/friends',
20 [UserRight.MANAGE_REQUEST_SCHEDULERS]: '/admin/requests/stats',
21 [UserRight.MANAGE_VIDEO_ABUSES]: '/admin/video-abuses',
22 [UserRight.MANAGE_VIDEO_BLACKLIST]: '/admin/video-blacklist'
23 }
14 24
15 constructor ( 25 constructor (
16 private authService: AuthService, 26 private authService: AuthService,
@@ -20,14 +30,17 @@ export class MenuComponent implements OnInit {
20 30
21 ngOnInit () { 31 ngOnInit () {
22 this.isLoggedIn = this.authService.isLoggedIn() 32 this.isLoggedIn = this.authService.isLoggedIn()
33 this.computeIsUserHasAdminAccess()
23 34
24 this.authService.loginChangedSource.subscribe( 35 this.authService.loginChangedSource.subscribe(
25 status => { 36 status => {
26 if (status === AuthStatus.LoggedIn) { 37 if (status === AuthStatus.LoggedIn) {
27 this.isLoggedIn = true 38 this.isLoggedIn = true
39 this.computeIsUserHasAdminAccess()
28 console.log('Logged in.') 40 console.log('Logged in.')
29 } else if (status === AuthStatus.LoggedOut) { 41 } else if (status === AuthStatus.LoggedOut) {
30 this.isLoggedIn = false 42 this.isLoggedIn = false
43 this.computeIsUserHasAdminAccess()
31 console.log('Logged out.') 44 console.log('Logged out.')
32 } else { 45 } else {
33 console.error('Unknown auth status: ' + status) 46 console.error('Unknown auth status: ' + status)
@@ -40,8 +53,31 @@ export class MenuComponent implements OnInit {
40 return this.serverService.getConfig().signup.allowed 53 return this.serverService.getConfig().signup.allowed
41 } 54 }
42 55
43 isUserAdmin () { 56 getFirstAdminRightAvailable () {
44 return this.authService.isAdmin() 57 const user = this.authService.getUser()
58 if (!user) return undefined
59
60 const adminRights = [
61 UserRight.MANAGE_USERS,
62 UserRight.MANAGE_PODS,
63 UserRight.MANAGE_REQUEST_SCHEDULERS,
64 UserRight.MANAGE_VIDEO_ABUSES,
65 UserRight.MANAGE_VIDEO_BLACKLIST
66 ]
67
68 for (const adminRight of adminRights) {
69 if (user.hasRight(adminRight)) {
70 return adminRight
71 }
72 }
73
74 return undefined
75 }
76
77 getFirstAdminRouteAvailable () {
78 const right = this.getFirstAdminRightAvailable()
79
80 return this.routesPerRight[right]
45 } 81 }
46 82
47 logout () { 83 logout () {
@@ -49,4 +85,10 @@ export class MenuComponent implements OnInit {
49 // Redirect to home page 85 // Redirect to home page
50 this.router.navigate(['/videos/list']) 86 this.router.navigate(['/videos/list'])
51 } 87 }
88
89 private computeIsUserHasAdminAccess () {
90 const right = this.getFirstAdminRightAvailable()
91
92 this.userHasAdminAccess = right !== undefined
93 }
52} 94}
diff --git a/client/src/app/core/routing/index.ts b/client/src/app/core/routing/index.ts
index 17f3ee833..d1b982834 100644
--- a/client/src/app/core/routing/index.ts
+++ b/client/src/app/core/routing/index.ts
@@ -1 +1,3 @@
1export * from './login-guard.service'
2export * from './user-right-guard.service'
1export * from './preload-selected-modules-list' 3export * from './preload-selected-modules-list'
diff --git a/client/src/app/core/auth/login-guard.service.ts b/client/src/app/core/routing/login-guard.service.ts
index c09e8fe97..18bc41ca6 100644
--- a/client/src/app/core/auth/login-guard.service.ts
+++ b/client/src/app/core/routing/login-guard.service.ts
@@ -7,7 +7,7 @@ import {
7 Router 7 Router
8} from '@angular/router' 8} from '@angular/router'
9 9
10import { AuthService } from './auth.service' 10import { AuthService } from '../auth/auth.service'
11 11
12@Injectable() 12@Injectable()
13export class LoginGuard implements CanActivate, CanActivateChild { 13export class LoginGuard implements CanActivate, CanActivateChild {
diff --git a/client/src/app/core/routing/user-right-guard.service.ts b/client/src/app/core/routing/user-right-guard.service.ts
new file mode 100644
index 000000000..65d029977
--- /dev/null
+++ b/client/src/app/core/routing/user-right-guard.service.ts
@@ -0,0 +1,35 @@
1import { Injectable } from '@angular/core'
2import {
3 ActivatedRouteSnapshot,
4 CanActivateChild,
5 RouterStateSnapshot,
6 CanActivate,
7 Router
8} from '@angular/router'
9
10import { AuthService } from '../auth'
11
12@Injectable()
13export class UserRightGuard implements CanActivate, CanActivateChild {
14
15 constructor (
16 private router: Router,
17 private auth: AuthService
18 ) {}
19
20 canActivate (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
21 const user = this.auth.getUser()
22 if (user) {
23 const neededUserRight = route.data.userRight
24
25 if (user.hasRight(neededUserRight)) return true
26 }
27
28 this.router.navigate([ '/login' ])
29 return false
30 }
31
32 canActivateChild (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
33 return this.canActivate(route, state)
34 }
35}