Kaynağa Gözat

changepermissions & 1 rankserver

master
peter 5 yıl önce
ebeveyn
işleme
c4ca96fef9

+ 3
- 3
package-lock.json Dosyayı Görüntüle

@@ -6130,9 +6130,9 @@
6130 6130
       }
6131 6131
     },
6132 6132
     "rpclibrary": {
6133
-      "version": "1.8.3",
6134
-      "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.8.3.tgz",
6135
-      "integrity": "sha512-8pQRbMXQKCf3+v+XM01d+1Bw73pg5YzgyhW/ACpYON1I4re5fZAjWGPyLc+ms+MlYQIlKc3Uk92PGot2sbb85Q==",
6133
+      "version": "1.9.2",
6134
+      "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.9.2.tgz",
6135
+      "integrity": "sha512-MOtVm0IBRLryXag1IwkYNPVFegbvW10+MbCjhr3GptO3MA7nHZ545ammgoCWnREtGOgFeN4Jib/EBDOJ9Ep41Q==",
6136 6136
       "requires": {
6137 6137
         "bsock": "^0.1.9",
6138 6138
         "http": "0.0.0",

+ 1
- 1
package.json Dosyayı Görüntüle

@@ -45,7 +45,7 @@
45 45
     "path": "^0.12.7",
46 46
     "reflect-metadata": "^0.1.13",
47 47
     "rimraf": "^3.0.0",
48
-    "rpclibrary": "^1.8.3",
48
+    "rpclibrary": "^1.9.2",
49 49
     "simple-git": "^1.124.0",
50 50
     "spawn-sync": "^2.0.0",
51 51
     "sqlite3": "^4.1.1",

+ 61
- 76
src/backend/Components/User/UserManager.ts Dosyayı Görüntüle

@@ -1,4 +1,4 @@
1
-import { RPCServer, Socket } from "rpclibrary";
1
+import { RPCServer, Socket, RPCInterface } from "rpclibrary";
2 2
 import { Inject, Injectable } from "../../Injector/ServiceDecorator";
3 3
 import { FrontworkAdmin } from "../../Admin/Admin";
4 4
 import { GuildManager } from "../Guild/GuildManager";
@@ -23,10 +23,9 @@ const uuid = require('uuid/v4')
23 23
 const salt = "6pIbc6yjSN"
24 24
 const ONE_WEEK = 604800000 
25 25
 
26
-type Serverstate = {
27
-    server: RPCServer,
26
+type Serverstate<SubresT, InterfaceT extends RPCInterface> = {
27
+    server: RPCServer<SubresT, InterfaceT>,
28 28
     port : number,
29
-    allowed: string[]
30 29
 };
31 30
 
32 31
 
@@ -51,8 +50,9 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
51 50
     private character : CharacterManager
52 51
     
53 52
     exporters :any[] = []
54
-    rankServers : {[rank in Rank] : Serverstate}
53
+    rankServer :  Serverstate<{}, FrontcraftFeatureIfc>
55 54
     userLogins : {[username in string] : UserRecord} = {}
55
+    allowed: string[] = []
56 56
 
57 57
     exportRPCs = () => [
58 58
         this.login,
@@ -145,19 +145,11 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
145 145
             }
146 146
         })))
147 147
 
148
-        //start rankServers
149
-        let rankServers = { } as any
150
-        await Promise.all(_Rank.map(async (r,i) => {
151
-            const port = 20001 + i
152
-            const rankServer = await this.startRankServer(r, port)
153
-            rankServers[r] = {
154
-                server: rankServer,
155
-                port: port,
156
-                allowed: []
157
-            }
158
-        }))
159
-        this.rankServers = rankServers
160
-        getLogger('UserManager').debug(Object.values(this.rankServers).length+" rank servers started")
148
+        const rankServer = await this.startRankServer(20001)
149
+        this.rankServer = {
150
+            server: rankServer,
151
+            port: 20001
152
+        }
161 153
         setInterval(this.checkExpiredSessions, 600_000)   
162 154
     }
163 155
 
@@ -166,20 +158,17 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
166 158
             Object.values(x.connections).forEach(c => c.destroy())
167 159
         })
168 160
 
169
-        Object.values(this.rankServers)
170
-        .map(state => {
171
-            try{
172
-                return state.server.destroy()
173
-            }catch(e){
174
-                getLogger('UserManager').warn(e)
175
-            }
176
-        })
161
+        try{
162
+            return this.rankServer.server.destroy()
163
+        }catch(e){
164
+            //getLogger('UserManager').warn(e)
165
+        }
177 166
     }
178 167
 
179 168
     checkExpiredSessions = () => {
180 169
         Object.values(this.userLogins).map(userLogin => {
181 170
             const auth = userLogin.auth
182
-            if(!this.checkToken(auth.token.value, auth.user.rank)){
171
+            if(!this.checkToken(auth.token.value)){
183 172
                 this.logout(auth.user.username, auth.token.value)
184 173
             }
185 174
         })
@@ -232,6 +221,13 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
232 221
         await this.admin.knex('rpcpermissions')
233 222
         .where('rpcname', '=', permission.rpcname)
234 223
         .update(permission)
224
+
225
+        await Promise.all(
226
+            Object.entries(this.userLogins).map(([username, record]) => {
227
+                if(record.user.rank === "ADMIN") return
228
+                return this.adminLogout(username)
229
+            })
230
+        )
235 231
     }
236 232
 
237 233
     getPermissions = async () : Promise<RPCPermission[]> => {
@@ -313,15 +309,10 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
313 309
                     await sock.call('kick')
314 310
                 }))
315 311
             
316
-                Object.values(this.rankServers)
317
-                .forEach(state => {
318
-                    state.allowed = state.allowed.filter(allowed => allowed !== this.userLogins[username].auth.token.value)
319
-                })
312
+                this.allowed = this.allowed.filter(allowed => allowed !== this.userLogins[username].auth.token.value)
320 313
                 delete this.userLogins[username]
321 314
             }
322
-        }catch(e){
323
-            getLogger('UserManager').warn(e)
324
-        }
315
+        }catch(e){}
325 316
     }
326 317
 
327 318
     wipeCurrency = async () => {
@@ -356,11 +347,11 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
356 347
             const userAuth : Auth = {
357 348
                 token: token,
358 349
                 user: user,
359
-                port: this.rankServers[user.rank].port
350
+                port: this.rankServer.port
360 351
             }
361 352
 
362 353
             this.userLogins[user.username] = {connections: {}, auth: userAuth, user:user}
363
-            this.rankServers[user.rank].allowed.push(token.value)
354
+            this.allowed.push(token.value)
364 355
             return userAuth 
365 356
         }
366 357
 
@@ -378,49 +369,43 @@ implements FrontworkComponent<UserManagerIfc, UserManagerFeatureIfc>, IUserManag
378 369
         return
379 370
     }
380 371
 
381
-    startRankServer = async (rank : Rank, port: number) : Promise<RPCServer> => {
382
-
383
-        const allowedRPCs = await this.getRPCForRank(rank)
384
-        let rpcServer
385
-        let n = 0
386
-        while(!rpcServer){
387
-            n++            
388
-            await Promise.race([
389
-                new Promise((res, rej) => {
390
-                    rpcServer = new RPCServer(port, allowedRPCs, {
391
-                        closeHandler: (socket) => { 
392
-                            Object.values(this.userLogins)
393
-                                .forEach(login => delete login.connections[socket.port])
394
-            
395
-                        },
396
-                        connectionHandler: (socket) => {
397
-                            this.checkConnection(socket).then(res => {
398
-                                if(!res){
399
-                                    socket.destroy();
400
-                                }
401
-                            }).catch((e) => {
402
-                                socket.destroy();
403
-                                getLogger('UserManager').warn(e);
404
-                            })
405
-                        },
406
-                        errorHandler: (socket, e, rpcName, args) => {
407
-                            getLogger('UserManager').error(rpcName, args, e);
408
-                        },
409
-                        sesame: (sesame) => this.checkToken(sesame, rank),
410
-                        visibility: '0.0.0.0'
411
-                    })
412
-                    res()
413
-                }),
414
-                new Promise((res, rej) => setTimeout(res, 500))
415
-            ])
416
-            if(!rpcServer && n>1) 
417
-                getLogger('UserManager').warn("createServer retry nr.", n, 'port', port)
418
-        }
372
+    startRankServer = async (port: number) : Promise<RPCServer<{},FrontcraftFeatureIfc>> => {
373
+        let rpcs = [
374
+            ...this.exportRPCFeatures(), 
375
+            ...this.exporters.flatMap((exp) => exp.exportRPCFeatures())
376
+        ]
377
+        let rpcServer = new RPCServer<{},FrontcraftFeatureIfc>(port, rpcs, {
378
+            accessFilter: async (sesame, exporter) => {
379
+                const record = this.getUserRecordByToken(sesame!)
380
+                if(!record) return false
381
+                return await this.getPermission(exporter.name, record.user.rank)
382
+            },
383
+            closeHandler: (socket) => { 
384
+                Object.values(this.userLogins)
385
+                    .forEach(login => delete login.connections[socket.port])
386
+
387
+            },
388
+            connectionHandler: (socket) => {
389
+                this.checkConnection(socket).then(res => {
390
+                    if(!res){
391
+                        socket.destroy();
392
+                    }
393
+                }).catch((e) => {
394
+                    socket.destroy();
395
+                })
396
+            },
397
+            errorHandler: (socket, e, rpcName, args) => {
398
+                getLogger('UserManager').error(rpcName, args, e);
399
+            },
400
+            sesame: (sesame) => this.checkToken(sesame),
401
+            visibility: '0.0.0.0'
402
+        })
403
+
419 404
         return rpcServer
420 405
     }
421 406
 
422
-    checkToken = (token: string, rank: Rank) : boolean => this.rankServers[rank].allowed.includes(token)
423
-                                                       && Object.values(this.userLogins).find(login => login.auth.token.value === token)!.auth.token.created > Date.now() - ONE_WEEK
407
+    checkToken = (token: string) : boolean => this.allowed.includes(token)
408
+                                            && Object.values(this.userLogins).find(login => login.auth.token.value === token)!.auth.token.created > Date.now() - ONE_WEEK
424 409
 
425 410
     checkTokenOwnedByUser = (username: string, tokenValue: string) => {
426 411
         username = username.toLowerCase()

+ 3
- 3
src/frontend/package-lock.json Dosyayı Görüntüle

@@ -17940,9 +17940,9 @@
17940 17940
       "integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ=="
17941 17941
     },
17942 17942
     "rpclibrary": {
17943
-      "version": "1.8.3",
17944
-      "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.8.3.tgz",
17945
-      "integrity": "sha512-8pQRbMXQKCf3+v+XM01d+1Bw73pg5YzgyhW/ACpYON1I4re5fZAjWGPyLc+ms+MlYQIlKc3Uk92PGot2sbb85Q==",
17943
+      "version": "1.9.2",
17944
+      "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.9.2.tgz",
17945
+      "integrity": "sha512-MOtVm0IBRLryXag1IwkYNPVFegbvW10+MbCjhr3GptO3MA7nHZ545ammgoCWnREtGOgFeN4Jib/EBDOJ9Ep41Q==",
17946 17946
       "requires": {
17947 17947
         "bsock": "^0.1.9",
17948 17948
         "http": "0.0.0",

+ 1
- 1
src/frontend/package.json Dosyayı Görüntüle

@@ -69,7 +69,7 @@
69 69
     "normalize.css": "6.0.0",
70 70
     "pace-js": "1.0.2",
71 71
     "roboto-fontface": "0.8.0",
72
-    "rpclibrary": "^1.8.3",
72
+    "rpclibrary": "^1.9.2",
73 73
     "rxjs": "6.5.2",
74 74
     "rxjs-compat": "6.3.0",
75 75
     "socicon": "3.0.5",

+ 5
- 1
src/frontend/src/app/@theme/components/header/header.component.html Dosyayı Görüntüle

@@ -9,7 +9,11 @@
9 9
 
10 10
 <div class="header-container">
11 11
   <nb-actions size="small">
12
-
12
+    <nb-action 
13
+      *ngIf="modifyPermissions"
14
+      icon="settings-2-outline" 
15
+      link="/permissions">
16
+    </nb-action>
13 17
     <nb-action 
14 18
       *ngIf="!newmessage"
15 19
       icon="message-square-outline" 

+ 2
- 1
src/frontend/src/app/@theme/components/header/header.component.ts Dosyayı Görüntüle

@@ -48,6 +48,7 @@ export class HeaderComponent implements OnInit, OnDestroy {
48 48
   chatlog: ShoutMessage[] = []
49 49
   newmessage = false
50 50
   lastmessage = "asdasd"
51
+  modifyPermissions
51 52
 
52 53
   constructor(private sidebarService: NbSidebarService,
53 54
               private router: Router,
@@ -62,7 +63,7 @@ export class HeaderComponent implements OnInit, OnDestroy {
62 63
     this.themeService.changeTheme("dark");
63 64
 
64 65
     this.currentTheme = this.themeService.currentTheme;
65
-
66
+    this.modifyPermissions = this.api.get('modifyPermissions')
66 67
     this.user = this.api.getCurrentUser()
67 68
     if(this.user)
68 69
       this.userMenu.unshift({ title: 'Profile', link: '/frontcraft/user/'+this.user.username });

+ 5
- 1
src/frontend/src/app/app-routing.module.ts Dosyayı Görüntüle

@@ -2,7 +2,11 @@ import { ExtraOptions, RouterModule, Routes } from '@angular/router';
2 2
 import { NgModule } from '@angular/core';
3 3
 
4 4
 const routes: Routes = [
5
-
5
+  {
6
+    path: 'permissions',
7
+    loadChildren: () => import('./frontcraft/permissions/permissions.module')
8
+      .then(m => m.PermissionsModule),
9
+  },
6 10
   {
7 11
     path: 'auth',
8 12
     loadChildren: () => import('./frontcraft/auth/auth.module')

+ 23
- 0
src/frontend/src/app/frontcraft/permissions/changePermissions/changePermissions.component.html Dosyayı Görüntüle

@@ -0,0 +1,23 @@
1
+  <nb-card>
2
+    <nb-card-body>
3
+      <table>
4
+        <tr>
5
+          <th>
6
+            Name
7
+          </th>
8
+          <th *ngFor="let rank of ranks">
9
+            {{rank}}
10
+          </th>
11
+        </tr>
12
+        <tr *ngFor="let perm of permissions">
13
+          <td>{{perm.rpcname}}</td>
14
+          <td *ngFor="let rank of ranks">
15
+            <nb-toggle 
16
+            [(ngModel)]="perm[rank]"
17
+            (checkedChange)="settingChanged($event, rank, perm)">
18
+            </nb-toggle>
19
+          </td>
20
+        </tr>
21
+      </table>
22
+    </nb-card-body>
23
+  </nb-card>

+ 43
- 0
src/frontend/src/app/frontcraft/permissions/changePermissions/changePermissions.component.ts Dosyayı Görüntüle

@@ -0,0 +1,43 @@
1
+import { Component, OnInit } from '@angular/core';
2
+import { ApiService as ApiService } from '../../services/login-api';
3
+import { Router } from '@angular/router';
4
+import { _Rank, _Class, _Race, RPCPermission  } from '../../../../../../backend/Types/Types'
5
+import { NbToastrService } from '@nebular/theme';
6
+
7
+
8
+@Component({
9
+  selector: 'changePermissions',
10
+  templateUrl: './changePermissions.component.html',
11
+})
12
+export class ChangePermissionsComponent implements OnInit{
13
+
14
+  permissions:RPCPermission[] = []
15
+  ranks = _Rank
16
+
17
+  constructor(
18
+    private router : Router,  
19
+    private api : ApiService,
20
+    private toastr: NbToastrService
21
+  ){}
22
+
23
+  async ngOnInit(){
24
+    const modify = this.api.get('modifyPermissions')
25
+    if(!modify) return
26
+    this.permissions = await modify.getPermissions()
27
+  }
28
+
29
+  settingChanged = async (value, key, perm:RPCPermission) => {
30
+    const modify = this.api.get('modifyPermissions')
31
+    if(!modify) return
32
+
33
+
34
+    perm[key] = value
35
+    console.log(perm);
36
+    
37
+
38
+    await modify.setPermission(perm).catch(e => {
39
+      
40
+    })
41
+    this.toastr.success('Permission updated', 'Success')
42
+  }
43
+}

+ 22
- 0
src/frontend/src/app/frontcraft/permissions/permissions-layout.component.ts Dosyayı Görüntüle

@@ -0,0 +1,22 @@
1
+import { Component, OnInit } from '@angular/core';
2
+import { ApiService } from '../services/login-api';
3
+import { Router } from '@angular/router';
4
+
5
+@Component({
6
+  selector: 'auth-layout',
7
+  template: `
8
+    <ngx-one-column-no-sidebar-layout>
9
+      <router-outlet></router-outlet>
10
+    </ngx-one-column-no-sidebar-layout>
11
+  `,
12
+})
13
+
14
+export class PermissionsComponent implements OnInit{
15
+  constructor(
16
+    private loginSvc : ApiService,
17
+    private router: Router  
18
+  ){}
19
+
20
+  ngOnInit(){
21
+  }
22
+}

+ 24
- 0
src/frontend/src/app/frontcraft/permissions/permissions-routing.module.ts Dosyayı Görüntüle

@@ -0,0 +1,24 @@
1
+import { NgModule } from '@angular/core';
2
+import { RouterModule, Routes } from '@angular/router';
3
+import { PermissionsComponent } from './permissions-layout.component';
4
+import { ChangePermissionsComponent } from './changePermissions/changePermissions.component';
5
+
6
+export const routes: Routes = [
7
+    {
8
+        path: '',
9
+        component: PermissionsComponent,
10
+        children: [
11
+            {
12
+                path: '**',
13
+                component: ChangePermissionsComponent,
14
+            },
15
+        ]
16
+    }
17
+];
18
+
19
+@NgModule({
20
+  imports: [RouterModule.forChild(routes)],
21
+  exports: [RouterModule],
22
+})
23
+export class PermissionsRoutingModule {
24
+}

+ 43
- 0
src/frontend/src/app/frontcraft/permissions/permissions.module.ts Dosyayı Görüntüle

@@ -0,0 +1,43 @@
1
+import { CommonModule } from '@angular/common';
2
+import { NgModule } from '@angular/core';
3
+import { FormsModule } from '@angular/forms';
4
+import { RouterModule } from '@angular/router';
5
+
6
+import { 
7
+  NbAlertModule,
8
+  NbButtonModule,
9
+  NbCheckboxModule,
10
+  NbInputModule,
11
+  NbMenuModule,
12
+  NbCardModule,
13
+  NbSelectModule,
14
+  NbToggleModule
15
+} from '@nebular/theme';
16
+import { PermissionsComponent } from './permissions-layout.component';
17
+import { ThemeModule } from '../../@theme/theme.module';
18
+import { PermissionsRoutingModule } from './permissions-routing.module';
19
+import { ChangePermissionsComponent } from './changePermissions/changePermissions.component';
20
+
21
+@NgModule({
22
+  imports: [
23
+    NbToggleModule,
24
+    PermissionsRoutingModule,
25
+    CommonModule,
26
+    FormsModule,
27
+    RouterModule,
28
+    NbAlertModule,
29
+    NbInputModule,
30
+    NbButtonModule,
31
+    NbCheckboxModule,
32
+    ThemeModule,
33
+    NbMenuModule,
34
+    NbCardModule,
35
+    NbSelectModule
36
+  ],
37
+  declarations: [
38
+    PermissionsComponent,
39
+    ChangePermissionsComponent,
40
+  ],
41
+})
42
+export class PermissionsModule {
43
+}

+ 6
- 1
src/frontend/src/app/frontcraft/services/login-api.ts Dosyayı Görüntüle

@@ -34,7 +34,7 @@ export class ApiService{
34 34
             )
35 35
 
36 36
             sock.hook('kick', () => {
37
-                this.logout()
37
+                this.kick()
38 38
             })
39 39
 
40 40
             sock.hook('getUserData', () => auth)
@@ -110,6 +110,11 @@ export class ApiService{
110 110
         return async (msg: ShoutMessage) => await this.get('Shoutbox').shout(res.uuid, msg)
111 111
     }
112 112
 
113
+    kick = async () => {
114
+        await this.logout()
115
+        location.reload()
116
+    }
117
+
113 118
     logout = async () => {
114 119
         this.cookieSvc.set('token', undefined)
115 120
         if(this.auth){

+ 21
- 7
test/backendTest.ts Dosyayı Görüntüle

@@ -129,6 +129,18 @@ describe('Frontcraft', () => {
129 129
         return client.UserManager.createUser(user)
130 130
     }
131 131
 
132
+    const login = async (name: string) : Promise<Auth> => {
133
+        const auth = await client.UserManager.login(name, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb')
134
+        
135
+        if(users[name]) users[name] = {
136
+            ...users[name],
137
+            auth: auth
138
+        }
139
+
140
+
141
+        return auth
142
+    }
143
+
132 144
     const createAccountAndUser = async (acc: protoAccount) => {
133 145
         const account = await createAccount({
134 146
             pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //sha256("a")
@@ -199,6 +211,14 @@ describe('Frontcraft', () => {
199 211
         server.stop()
200 212
     })
201 213
 
214
+    it('can set permissions', (done) => {
215
+        Promise.all(
216
+            defaultPermissions.map(perm => adminClient.modifyPermissions.setPermission(perm)),
217
+        ).then(_ => {
218
+            done()
219
+        })
220
+    })
221
+
202 222
     it('create raids', (done) => {
203 223
         let insertRaid = <Raid>{
204 224
             description: "Test raid 1",
@@ -587,13 +607,7 @@ describe('Frontcraft', () => {
587 607
         })
588 608
     })
589 609
 
590
-    it('can set permissions', (done) => {
591
-        Promise.all(
592
-            defaultPermissions.map(perm => adminClient.modifyPermissions.setPermission(perm)),
593
-        ).then(_ => {
594
-            done()
595
-        })
596
-    })
610
+
597 611
 
598 612
     it('start raid', (done) => {
599 613
         client.RaidManager.getRaids().then((r) => {

Loading…
İptal
Kaydet