flat-file based usermanagemant implemented for memoryBasedDB

This commit is contained in:
Braun Patrik 2016-07-07 12:19:08 +02:00
parent 8c04f56c52
commit ca0de09881
12 changed files with 120 additions and 23 deletions

View File

@ -9,6 +9,7 @@ import {ObjectManagerRepository} from "../../model/ObjectManagerRepository";
export class AuthenticationMWs { export class AuthenticationMWs {
public static authenticate(req:Request, res:Response, next:NextFunction) { public static authenticate(req:Request, res:Response, next:NextFunction) {
if (typeof req.session.user === 'undefined') { if (typeof req.session.user === 'undefined') {
return next(new Error(ErrorCodes.NOT_AUTHENTICATED)); return next(new Error(ErrorCodes.NOT_AUTHENTICATED));
} }

View File

@ -1,38 +1,93 @@
import {User, UserRoles} from "../../../common/entities/User"; import {User, UserRoles} from "../../../common/entities/User";
import {IUserManager} from "../IUserManager"; import {IUserManager} from "../IUserManager";
export class UserManager implements IUserManager { import {ProjectPath} from "../../ProjectPath";
import {Utils} from "../../../common/Utils";
import * as flatfile from "flat-file-db";
import * as path from "path";
export class UserManager implements IUserManager {
private db:any = null;
generateId():string {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + s4() + s4();
}
constructor() {
console.log("ctor");
this.db = flatfile.sync(path.join(ProjectPath.Root, 'users.db'));
if (!this.db.has("idCounter")) {
console.log("creating counter");
this.db.put("idCounter", 1);
}
if (!this.db.has("users")) {
this.db.put("users", []);
this.createUser(new User("developer", "developer", UserRoles.Developer));
this.createUser(new User("admin", "admin", UserRoles.Admin));
this.createUser(new User("user", "user", UserRoles.User));
this.createUser(new User("guest", "guest", UserRoles.Guest));
}
}
private users = [new User(1, "developer", "developer", UserRoles.Developer),
new User(2, "admin", "admin", UserRoles.Admin),
new User(3, "user", "user", UserRoles.User),
new User(4, "guest", "guest", UserRoles.Guest)];
public findOne(filter, cb:(error:any, result:User) => void) { public findOne(filter, cb:(error:any, result:User) => void) {
return cb(null, this.users[1]); this.find(filter, (error, result:Array<User>)=> {
if (error) {
return cb(error, null);
}
if (result.length == 0) {
return cb("User not found", null);
}
return cb(null, result[0]);
});
} }
public find(filter, cb:(error:any, result:Array<User>) => void) { public find(filter, cb:(error:any, result:Array<User>) => void) {
return cb(null, this.users);
let users = this.db.get("users").filter((u) => Utils.equalsFilter(u, filter));
return cb(null, users);
} }
public createUser(user, cb:(error:any, result:User) => void) { public createUser(user:User, cb:(error:any, result:User) => void = (e, r) => {
}) {
user.id = parseInt(this.db.get("idCounter")) + 1;
this.db.put("idCounter", user.id);
let users = this.db.get("users");
users.push(user);
this.users.push(user); this.db.put("users", users);
return cb(null, user); return cb(null, user);
} }
public deleteUser(id:number, cb:(error:any) => void) { public deleteUser(id:number, cb:(error:any) => void) {
this.users = this.users.filter(u => u.id != id); let users = this.db.get("users").filter((u) => u.id != id);
this.db.put("users", users);
return cb(null); return cb(null);
} }
public changeRole(id:number, newRole:UserRoles, cb:(error:any, result:string) => void) { public changeRole(id:number, newRole:UserRoles, cb:(error:any, result:string) => void) {
for (let i = 0; i < this.users.length; i++) {
if (this.users[i].id === id) { let users:Array<User> = this.db.get("users");
this.users[i].role = newRole;
return cb(null, "ok"); for (let i = 0; i < users.length; i++) {
if (users[i].id == id) {
users[i].role = newRole;
break;
} }
} }
this.db.put("users", users);
} }
public changePassword(request:any, cb:(error:any, result:string) => void) { public changePassword(request:any, cb:(error:any, result:string) => void) {

View File

@ -0,0 +1,13 @@
declare module "flat-file-db" {
export function sync(path:string):DB;
}
declare interface DB {
sync();
put();
get();
del();
has();
keys();
close();
}

View File

@ -27,7 +27,6 @@ export class Server {
this.debug = _debug("PiGallery2:server"); this.debug = _debug("PiGallery2:server");
this.app = _express(); this.app = _express();
this.app.set('view engine', 'ejs'); this.app.set('view engine', 'ejs');
if (process.env.DEBUG) { if (process.env.DEBUG) {

View File

@ -1,9 +1,23 @@
export class Utils { export class Utils {
static clone<T>(object:T):T { static clone<T>(object:T):T {
return JSON.parse(JSON.stringify(object)); return JSON.parse(JSON.stringify(object));
} }
static equalsFilter(object:any, filter:any):boolean {
let keys = Object.keys(filter);
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
if (object[key] !== filter[key]) {
return false;
}
}
return true;
}
static concatUrls(...args:Array<string>) { static concatUrls(...args:Array<string>) {
let url = ""; let url = "";

View File

@ -22,6 +22,7 @@ interface ClientConfig {
enableCache:boolean; enableCache:boolean;
enableOnScrollRendering:boolean; enableOnScrollRendering:boolean;
enableOnScrollThumbnailPrioritising:boolean; enableOnScrollThumbnailPrioritising:boolean;
authenticationRequired:boolean;
} }
export class ConfigClass { export class ConfigClass {
@ -37,7 +38,8 @@ export class ConfigClass {
concurrentThumbnailGenerations: 1, concurrentThumbnailGenerations: 1,
enableCache: false, enableCache: false,
enableOnScrollRendering: true, enableOnScrollRendering: true,
enableOnScrollThumbnailPrioritising: true enableOnScrollThumbnailPrioritising: true,
authenticationRequired: true
}; };
public setDatabaseType(type:DatabaseType) { public setDatabaseType(type:DatabaseType) {

View File

@ -7,6 +7,8 @@ export enum UserRoles{
} }
export class User { export class User {
constructor(public id?:number, public name?:string, public password?:string, public role:UserRoles = UserRoles.User) { public id:number;
constructor(public name?:string, public password?:string, public role:UserRoles = UserRoles.User) {
} }
} }

View File

@ -15,7 +15,7 @@
<li class="active"><a [routerLink]="['Gallery',{directory: '/'}]">Gallery</a></li> <li class="active"><a [routerLink]="['Gallery',{directory: '/'}]">Gallery</a></li>
<li><a [routerLink]="['Admin']">Admin</a></li> <li><a [routerLink]="['Admin']">Admin</a></li>
</ul> </ul>
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right" *ngIf="authenticationRequired">
<li> <li>
<p class="navbar-text" *ngIf="user">{{user.name}}</p> <p class="navbar-text" *ngIf="user">{{user.name}}</p>
</li> </li>

View File

@ -4,6 +4,7 @@ import {Component, ViewEncapsulation} from "@angular/core";
import {RouterLink} from "@angular/router-deprecated"; import {RouterLink} from "@angular/router-deprecated";
import {AuthenticationService} from "../model/network/authentication.service"; import {AuthenticationService} from "../model/network/authentication.service";
import {User} from "../../../common/entities/User"; import {User} from "../../../common/entities/User";
import {Config} from "../config/Config";
@Component({ @Component({
selector: 'app-frame', selector: 'app-frame',
@ -14,11 +15,14 @@ import {User} from "../../../common/entities/User";
export class FrameComponent { export class FrameComponent {
user:User; user:User;
authenticationRequired:boolean = false;
constructor(private _authService:AuthenticationService) { constructor(private _authService:AuthenticationService) {
this.user = this._authService.getUser(); this.user = this._authService.getUser();
this.authenticationRequired = Config.Client.authenticationRequired;
} }
logout() { logout() {
this._authService.logout(); this._authService.logout();
} }

View File

@ -11,7 +11,7 @@ import {AuthenticationService} from "./authentication.service";
class MockUserService { class MockUserService {
public login(credential:LoginCredential) { public login(credential:LoginCredential) {
return Promise.resolve(new Message<User>(null, new User(0, "testUserName"))) return Promise.resolve(new Message<User>(null, new User("testUserName")))
} }
} }

View File

@ -1,13 +1,14 @@
///<reference path="../../../browser.d.ts"/> ///<reference path="../../../browser.d.ts"/>
import {Injectable} from "@angular/core"; import {Injectable} from "@angular/core";
import {User} from "../../../../common/entities/User"; import {User, UserRoles} from "../../../../common/entities/User";
import {Event} from "../../../../common/event/Event"; import {Event} from "../../../../common/event/Event";
import {UserService} from "./user.service.ts"; import {UserService} from "./user.service.ts";
import {LoginCredential} from "../../../../common/entities/LoginCredential"; import {LoginCredential} from "../../../../common/entities/LoginCredential";
import {Message} from "../../../../common/entities/Message"; import {Message} from "../../../../common/entities/Message";
import {Cookie} from "ng2-cookies/ng2-cookies"; import {Cookie} from "ng2-cookies/ng2-cookies";
import {ErrorCodes} from "../../../../common/entities/Error"; import {ErrorCodes} from "../../../../common/entities/Error";
import {Config} from "../../config/Config";
declare module ServerInject { declare module ServerInject {
export var user; export var user;
@ -52,7 +53,7 @@ export class AuthenticationService {
public login(credential:LoginCredential) { public login(credential:LoginCredential) {
this._userService.login(credential).then((message:Message<User>) => { this._userService.login(credential).then((message:Message<User>) => {
if (message.error) { if (message.error) {
console.log(ErrorCodes[message.error.code] + "message: " + message.error.message); console.log(ErrorCodes[message.error.code] + ", message: " + message.error.message);
} else { } else {
this.setUser(message.result); this.setUser(message.result);
} }
@ -61,10 +62,16 @@ export class AuthenticationService {
public isAuthenticated():boolean { public isAuthenticated():boolean {
if (Config.Client.authenticationRequired === false) {
return true;
}
return (this._user && this._user != null) ? true : false; return (this._user && this._user != null) ? true : false;
} }
public getUser() { public getUser() {
if (Config.Client.authenticationRequired === false) {
return new User("", "", UserRoles.Admin);
}
return this._user; return this._user;
} }

View File

@ -21,16 +21,15 @@
"url": "https://github.com/bpatrik/PiGallery2/issues" "url": "https://github.com/bpatrik/PiGallery2/issues"
}, },
"dependencies": { "dependencies": {
"@angular/http": "2.0.0-rc.4",
"@angular/common": "2.0.0-rc.4", "@angular/common": "2.0.0-rc.4",
"@angular/compiler": "2.0.0-rc.4", "@angular/compiler": "2.0.0-rc.4",
"@angular/core": "2.0.0-rc.4", "@angular/core": "2.0.0-rc.4",
"@angular/forms": "^0.2.0", "@angular/forms": "^0.2.0",
"@angular/http": "2.0.0-rc.4",
"@angular/platform-browser": "2.0.0-rc.4", "@angular/platform-browser": "2.0.0-rc.4",
"@angular/platform-browser-dynamic": "2.0.0-rc.4", "@angular/platform-browser-dynamic": "2.0.0-rc.4",
"@angular/platform-server": "2.0.0-rc.4", "@angular/platform-server": "2.0.0-rc.4",
"@angular/router": "3.0.0-beta.2", "@angular/router": "3.0.0-beta.2",
"@angular/router-deprecated": "2.0.0-rc.2", "@angular/router-deprecated": "2.0.0-rc.2",
"body-parser": "^1.15.2", "body-parser": "^1.15.2",
"chai": "^3.5.0", "chai": "^3.5.0",
@ -46,6 +45,7 @@
"express": "^4.14.0", "express": "^4.14.0",
"express-session": "^1.14.0", "express-session": "^1.14.0",
"file-loader": "^0.8.5", "file-loader": "^0.8.5",
"flat-file-db": "^1.0.0",
"html-webpack-plugin": "^2.22.0", "html-webpack-plugin": "^2.22.0",
"ie-shim": "^0.1.0", "ie-shim": "^0.1.0",
"imports-loader": "^0.6.5", "imports-loader": "^0.6.5",