From c4ca96fef91e6cff9e4319e9bcf0a7afc43d736d Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 5 Mar 2020 20:36:19 +0100 Subject: [PATCH] changepermissions & 1 rankserver --- package-lock.json | 6 +- package.json | 2 +- src/backend/Components/User/UserManager.ts | 135 ++++++++---------- src/frontend/package-lock.json | 6 +- src/frontend/package.json | 2 +- .../components/header/header.component.html | 6 +- .../components/header/header.component.ts | 3 +- src/frontend/src/app/app-routing.module.ts | 6 +- .../changePermissions.component.html | 23 +++ .../changePermissions.component.ts | 43 ++++++ .../permissions-layout.component.ts | 22 +++ .../permissions/permissions-routing.module.ts | 24 ++++ .../permissions/permissions.module.ts | 43 ++++++ .../src/app/frontcraft/services/login-api.ts | 7 +- test/backendTest.ts | 28 +++- 15 files changed, 262 insertions(+), 94 deletions(-) create mode 100644 src/frontend/src/app/frontcraft/permissions/changePermissions/changePermissions.component.html create mode 100644 src/frontend/src/app/frontcraft/permissions/changePermissions/changePermissions.component.ts create mode 100644 src/frontend/src/app/frontcraft/permissions/permissions-layout.component.ts create mode 100644 src/frontend/src/app/frontcraft/permissions/permissions-routing.module.ts create mode 100644 src/frontend/src/app/frontcraft/permissions/permissions.module.ts diff --git a/package-lock.json b/package-lock.json index a1cf608..44f8cc6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6130,9 +6130,9 @@ } }, "rpclibrary": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.8.3.tgz", - "integrity": "sha512-8pQRbMXQKCf3+v+XM01d+1Bw73pg5YzgyhW/ACpYON1I4re5fZAjWGPyLc+ms+MlYQIlKc3Uk92PGot2sbb85Q==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.9.2.tgz", + "integrity": "sha512-MOtVm0IBRLryXag1IwkYNPVFegbvW10+MbCjhr3GptO3MA7nHZ545ammgoCWnREtGOgFeN4Jib/EBDOJ9Ep41Q==", "requires": { "bsock": "^0.1.9", "http": "0.0.0", diff --git a/package.json b/package.json index f6e95bf..a487c6e 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "path": "^0.12.7", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.0", - "rpclibrary": "^1.8.3", + "rpclibrary": "^1.9.2", "simple-git": "^1.124.0", "spawn-sync": "^2.0.0", "sqlite3": "^4.1.1", diff --git a/src/backend/Components/User/UserManager.ts b/src/backend/Components/User/UserManager.ts index 33a9abb..c88331b 100644 --- a/src/backend/Components/User/UserManager.ts +++ b/src/backend/Components/User/UserManager.ts @@ -1,4 +1,4 @@ -import { RPCServer, Socket } from "rpclibrary"; +import { RPCServer, Socket, RPCInterface } from "rpclibrary"; import { Inject, Injectable } from "../../Injector/ServiceDecorator"; import { FrontworkAdmin } from "../../Admin/Admin"; import { GuildManager } from "../Guild/GuildManager"; @@ -23,10 +23,9 @@ const uuid = require('uuid/v4') const salt = "6pIbc6yjSN" const ONE_WEEK = 604800000 -type Serverstate = { - server: RPCServer, +type Serverstate = { + server: RPCServer, port : number, - allowed: string[] }; @@ -51,8 +50,9 @@ implements FrontworkComponent, IUserManag private character : CharacterManager exporters :any[] = [] - rankServers : {[rank in Rank] : Serverstate} + rankServer : Serverstate<{}, FrontcraftFeatureIfc> userLogins : {[username in string] : UserRecord} = {} + allowed: string[] = [] exportRPCs = () => [ this.login, @@ -145,19 +145,11 @@ implements FrontworkComponent, IUserManag } }))) - //start rankServers - let rankServers = { } as any - await Promise.all(_Rank.map(async (r,i) => { - const port = 20001 + i - const rankServer = await this.startRankServer(r, port) - rankServers[r] = { - server: rankServer, - port: port, - allowed: [] - } - })) - this.rankServers = rankServers - getLogger('UserManager').debug(Object.values(this.rankServers).length+" rank servers started") + const rankServer = await this.startRankServer(20001) + this.rankServer = { + server: rankServer, + port: 20001 + } setInterval(this.checkExpiredSessions, 600_000) } @@ -166,20 +158,17 @@ implements FrontworkComponent, IUserManag Object.values(x.connections).forEach(c => c.destroy()) }) - Object.values(this.rankServers) - .map(state => { - try{ - return state.server.destroy() - }catch(e){ - getLogger('UserManager').warn(e) - } - }) + try{ + return this.rankServer.server.destroy() + }catch(e){ + //getLogger('UserManager').warn(e) + } } checkExpiredSessions = () => { Object.values(this.userLogins).map(userLogin => { const auth = userLogin.auth - if(!this.checkToken(auth.token.value, auth.user.rank)){ + if(!this.checkToken(auth.token.value)){ this.logout(auth.user.username, auth.token.value) } }) @@ -232,6 +221,13 @@ implements FrontworkComponent, IUserManag await this.admin.knex('rpcpermissions') .where('rpcname', '=', permission.rpcname) .update(permission) + + await Promise.all( + Object.entries(this.userLogins).map(([username, record]) => { + if(record.user.rank === "ADMIN") return + return this.adminLogout(username) + }) + ) } getPermissions = async () : Promise => { @@ -313,15 +309,10 @@ implements FrontworkComponent, IUserManag await sock.call('kick') })) - Object.values(this.rankServers) - .forEach(state => { - state.allowed = state.allowed.filter(allowed => allowed !== this.userLogins[username].auth.token.value) - }) + this.allowed = this.allowed.filter(allowed => allowed !== this.userLogins[username].auth.token.value) delete this.userLogins[username] } - }catch(e){ - getLogger('UserManager').warn(e) - } + }catch(e){} } wipeCurrency = async () => { @@ -356,11 +347,11 @@ implements FrontworkComponent, IUserManag const userAuth : Auth = { token: token, user: user, - port: this.rankServers[user.rank].port + port: this.rankServer.port } this.userLogins[user.username] = {connections: {}, auth: userAuth, user:user} - this.rankServers[user.rank].allowed.push(token.value) + this.allowed.push(token.value) return userAuth } @@ -378,49 +369,43 @@ implements FrontworkComponent, IUserManag return } - startRankServer = async (rank : Rank, port: number) : Promise => { + startRankServer = async (port: number) : Promise> => { + let rpcs = [ + ...this.exportRPCFeatures(), + ...this.exporters.flatMap((exp) => exp.exportRPCFeatures()) + ] + let rpcServer = new RPCServer<{},FrontcraftFeatureIfc>(port, rpcs, { + accessFilter: async (sesame, exporter) => { + const record = this.getUserRecordByToken(sesame!) + if(!record) return false + return await this.getPermission(exporter.name, record.user.rank) + }, + closeHandler: (socket) => { + Object.values(this.userLogins) + .forEach(login => delete login.connections[socket.port]) + + }, + connectionHandler: (socket) => { + this.checkConnection(socket).then(res => { + if(!res){ + socket.destroy(); + } + }).catch((e) => { + socket.destroy(); + }) + }, + errorHandler: (socket, e, rpcName, args) => { + getLogger('UserManager').error(rpcName, args, e); + }, + sesame: (sesame) => this.checkToken(sesame), + visibility: '0.0.0.0' + }) - const allowedRPCs = await this.getRPCForRank(rank) - let rpcServer - let n = 0 - while(!rpcServer){ - n++ - await Promise.race([ - new Promise((res, rej) => { - rpcServer = new RPCServer(port, allowedRPCs, { - closeHandler: (socket) => { - Object.values(this.userLogins) - .forEach(login => delete login.connections[socket.port]) - - }, - connectionHandler: (socket) => { - this.checkConnection(socket).then(res => { - if(!res){ - socket.destroy(); - } - }).catch((e) => { - socket.destroy(); - getLogger('UserManager').warn(e); - }) - }, - errorHandler: (socket, e, rpcName, args) => { - getLogger('UserManager').error(rpcName, args, e); - }, - sesame: (sesame) => this.checkToken(sesame, rank), - visibility: '0.0.0.0' - }) - res() - }), - new Promise((res, rej) => setTimeout(res, 500)) - ]) - if(!rpcServer && n>1) - getLogger('UserManager').warn("createServer retry nr.", n, 'port', port) - } return rpcServer } - checkToken = (token: string, rank: Rank) : boolean => this.rankServers[rank].allowed.includes(token) - && Object.values(this.userLogins).find(login => login.auth.token.value === token)!.auth.token.created > Date.now() - ONE_WEEK + checkToken = (token: string) : boolean => this.allowed.includes(token) + && Object.values(this.userLogins).find(login => login.auth.token.value === token)!.auth.token.created > Date.now() - ONE_WEEK checkTokenOwnedByUser = (username: string, tokenValue: string) => { username = username.toLowerCase() diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index 1113eed..602d857 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -17940,9 +17940,9 @@ "integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ==" }, "rpclibrary": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.8.3.tgz", - "integrity": "sha512-8pQRbMXQKCf3+v+XM01d+1Bw73pg5YzgyhW/ACpYON1I4re5fZAjWGPyLc+ms+MlYQIlKc3Uk92PGot2sbb85Q==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/rpclibrary/-/rpclibrary-1.9.2.tgz", + "integrity": "sha512-MOtVm0IBRLryXag1IwkYNPVFegbvW10+MbCjhr3GptO3MA7nHZ545ammgoCWnREtGOgFeN4Jib/EBDOJ9Ep41Q==", "requires": { "bsock": "^0.1.9", "http": "0.0.0", diff --git a/src/frontend/package.json b/src/frontend/package.json index 0bfff28..c838cf3 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -69,7 +69,7 @@ "normalize.css": "6.0.0", "pace-js": "1.0.2", "roboto-fontface": "0.8.0", - "rpclibrary": "^1.8.3", + "rpclibrary": "^1.9.2", "rxjs": "6.5.2", "rxjs-compat": "6.3.0", "socicon": "3.0.5", diff --git a/src/frontend/src/app/@theme/components/header/header.component.html b/src/frontend/src/app/@theme/components/header/header.component.html index 4ecff79..20c18d4 100644 --- a/src/frontend/src/app/@theme/components/header/header.component.html +++ b/src/frontend/src/app/@theme/components/header/header.component.html @@ -9,7 +9,11 @@
- + + import('./frontcraft/permissions/permissions.module') + .then(m => m.PermissionsModule), + }, { path: 'auth', loadChildren: () => import('./frontcraft/auth/auth.module') diff --git a/src/frontend/src/app/frontcraft/permissions/changePermissions/changePermissions.component.html b/src/frontend/src/app/frontcraft/permissions/changePermissions/changePermissions.component.html new file mode 100644 index 0000000..c56ad7e --- /dev/null +++ b/src/frontend/src/app/frontcraft/permissions/changePermissions/changePermissions.component.html @@ -0,0 +1,23 @@ + + + + + + + + + + + +
+ Name + + {{rank}} +
{{perm.rpcname}} + + +
+
+
diff --git a/src/frontend/src/app/frontcraft/permissions/changePermissions/changePermissions.component.ts b/src/frontend/src/app/frontcraft/permissions/changePermissions/changePermissions.component.ts new file mode 100644 index 0000000..a26c326 --- /dev/null +++ b/src/frontend/src/app/frontcraft/permissions/changePermissions/changePermissions.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit } from '@angular/core'; +import { ApiService as ApiService } from '../../services/login-api'; +import { Router } from '@angular/router'; +import { _Rank, _Class, _Race, RPCPermission } from '../../../../../../backend/Types/Types' +import { NbToastrService } from '@nebular/theme'; + + +@Component({ + selector: 'changePermissions', + templateUrl: './changePermissions.component.html', +}) +export class ChangePermissionsComponent implements OnInit{ + + permissions:RPCPermission[] = [] + ranks = _Rank + + constructor( + private router : Router, + private api : ApiService, + private toastr: NbToastrService + ){} + + async ngOnInit(){ + const modify = this.api.get('modifyPermissions') + if(!modify) return + this.permissions = await modify.getPermissions() + } + + settingChanged = async (value, key, perm:RPCPermission) => { + const modify = this.api.get('modifyPermissions') + if(!modify) return + + + perm[key] = value + console.log(perm); + + + await modify.setPermission(perm).catch(e => { + + }) + this.toastr.success('Permission updated', 'Success') + } +} \ No newline at end of file diff --git a/src/frontend/src/app/frontcraft/permissions/permissions-layout.component.ts b/src/frontend/src/app/frontcraft/permissions/permissions-layout.component.ts new file mode 100644 index 0000000..9ad350b --- /dev/null +++ b/src/frontend/src/app/frontcraft/permissions/permissions-layout.component.ts @@ -0,0 +1,22 @@ +import { Component, OnInit } from '@angular/core'; +import { ApiService } from '../services/login-api'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'auth-layout', + template: ` + + + + `, +}) + +export class PermissionsComponent implements OnInit{ + constructor( + private loginSvc : ApiService, + private router: Router + ){} + + ngOnInit(){ + } +} diff --git a/src/frontend/src/app/frontcraft/permissions/permissions-routing.module.ts b/src/frontend/src/app/frontcraft/permissions/permissions-routing.module.ts new file mode 100644 index 0000000..5022ddf --- /dev/null +++ b/src/frontend/src/app/frontcraft/permissions/permissions-routing.module.ts @@ -0,0 +1,24 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { PermissionsComponent } from './permissions-layout.component'; +import { ChangePermissionsComponent } from './changePermissions/changePermissions.component'; + +export const routes: Routes = [ + { + path: '', + component: PermissionsComponent, + children: [ + { + path: '**', + component: ChangePermissionsComponent, + }, + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class PermissionsRoutingModule { +} \ No newline at end of file diff --git a/src/frontend/src/app/frontcraft/permissions/permissions.module.ts b/src/frontend/src/app/frontcraft/permissions/permissions.module.ts new file mode 100644 index 0000000..961c1d1 --- /dev/null +++ b/src/frontend/src/app/frontcraft/permissions/permissions.module.ts @@ -0,0 +1,43 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import { + NbAlertModule, + NbButtonModule, + NbCheckboxModule, + NbInputModule, + NbMenuModule, + NbCardModule, + NbSelectModule, + NbToggleModule +} from '@nebular/theme'; +import { PermissionsComponent } from './permissions-layout.component'; +import { ThemeModule } from '../../@theme/theme.module'; +import { PermissionsRoutingModule } from './permissions-routing.module'; +import { ChangePermissionsComponent } from './changePermissions/changePermissions.component'; + +@NgModule({ + imports: [ + NbToggleModule, + PermissionsRoutingModule, + CommonModule, + FormsModule, + RouterModule, + NbAlertModule, + NbInputModule, + NbButtonModule, + NbCheckboxModule, + ThemeModule, + NbMenuModule, + NbCardModule, + NbSelectModule + ], + declarations: [ + PermissionsComponent, + ChangePermissionsComponent, + ], +}) +export class PermissionsModule { +} \ No newline at end of file diff --git a/src/frontend/src/app/frontcraft/services/login-api.ts b/src/frontend/src/app/frontcraft/services/login-api.ts index 829c8ed..efa0068 100644 --- a/src/frontend/src/app/frontcraft/services/login-api.ts +++ b/src/frontend/src/app/frontcraft/services/login-api.ts @@ -34,7 +34,7 @@ export class ApiService{ ) sock.hook('kick', () => { - this.logout() + this.kick() }) sock.hook('getUserData', () => auth) @@ -110,6 +110,11 @@ export class ApiService{ return async (msg: ShoutMessage) => await this.get('Shoutbox').shout(res.uuid, msg) } + kick = async () => { + await this.logout() + location.reload() + } + logout = async () => { this.cookieSvc.set('token', undefined) if(this.auth){ diff --git a/test/backendTest.ts b/test/backendTest.ts index 34da30f..51096b0 100644 --- a/test/backendTest.ts +++ b/test/backendTest.ts @@ -129,6 +129,18 @@ describe('Frontcraft', () => { return client.UserManager.createUser(user) } + const login = async (name: string) : Promise => { + const auth = await client.UserManager.login(name, 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb') + + if(users[name]) users[name] = { + ...users[name], + auth: auth + } + + + return auth + } + const createAccountAndUser = async (acc: protoAccount) => { const account = await createAccount({ pwhash: 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', //sha256("a") @@ -199,6 +211,14 @@ describe('Frontcraft', () => { server.stop() }) + it('can set permissions', (done) => { + Promise.all( + defaultPermissions.map(perm => adminClient.modifyPermissions.setPermission(perm)), + ).then(_ => { + done() + }) + }) + it('create raids', (done) => { let insertRaid = { description: "Test raid 1", @@ -587,13 +607,7 @@ describe('Frontcraft', () => { }) }) - it('can set permissions', (done) => { - Promise.all( - defaultPermissions.map(perm => adminClient.modifyPermissions.setPermission(perm)), - ).then(_ => { - done() - }) - }) + it('start raid', (done) => { client.RaidManager.getRaids().then((r) => {