implementing user listing and role changing

This commit is contained in:
Braun Patrik 2016-05-03 14:29:24 +02:00
parent 67d4d2be71
commit 11be4e3e87
15 changed files with 160 additions and 56 deletions

View File

@ -1,5 +1,6 @@
import {ConfigLoader} from "./ConfigLoader"; import {ConfigLoader} from "./ConfigLoader";
import * as path from "path";
export enum DatabaseType{ export enum DatabaseType{
memory, mongoDB memory, mongoDB
@ -8,7 +9,7 @@ export enum DatabaseType{
export class ConfigClass{ export class ConfigClass{
constructor(){ constructor(){
ConfigLoader.init(this,__dirname+'./../../config.json'); ConfigLoader.init(this,path.join(__dirname,'./../../config.json'));
} }
public PORT:number = 80; public PORT:number = 80;

View File

@ -3,6 +3,7 @@ import {UserManager} from "../model/memory/UserManager";
import {NextFunction, Request, Response} from "express"; import {NextFunction, Request, Response} from "express";
import {Error, ErrorCodes} from "../../common/entities/Error"; import {Error, ErrorCodes} from "../../common/entities/Error";
import {ObjectManagerRepository} from "../model/ObjectManagerRepository"; import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
import {User} from "../../common/entities/User";
export class UserMWs { export class UserMWs {
@ -40,12 +41,11 @@ export class UserMWs {
} }
public static deleteUser(req:Request, res:Response, next:NextFunction){ public static deleteUser(req:Request, res:Response, next:NextFunction){
if ((typeof req.body === 'undefined') || (typeof req.body.newUser === 'undefined') if ((typeof req.params === 'undefined') || (typeof req.params.id === 'undefined')) {
|| (typeof req.body.userModReq.id === 'undefined')) {
return next(); return next();
} }
ObjectManagerRepository.getInstance().getUserManager().deleteUser(req.body.userModReq.id, (err, result) =>{ ObjectManagerRepository.getInstance().getUserManager().deleteUser(req.params.id, (err, result) =>{
if ((err) || (!result)) { if ((err) || (!result)) {
return next(new Error(ErrorCodes.GENERAL_ERROR)); return next(new Error(ErrorCodes.GENERAL_ERROR));
} }
@ -57,13 +57,12 @@ export class UserMWs {
} }
public static changeRole(req:Request, res:Response, next:NextFunction){ public static changeRole(req:Request, res:Response, next:NextFunction){
if ((typeof req.body === 'undefined') || (typeof req.body.userModReq === 'undefined') if ((typeof req.params === 'undefined') || (typeof req.params.id === 'undefined')
|| (typeof req.body.userModReq.id === 'undefined') || (typeof req.body === 'undefined') || (typeof req.body.newRole === 'undefined')) {
|| (typeof req.body.userModReq.newRole === 'undefined')) {
return next(); return next();
} }
ObjectManagerRepository.getInstance().getUserManager().changeRole(req.body.userModReq, (err) =>{ ObjectManagerRepository.getInstance().getUserManager().changeRole(req.params.id,req.body.newRole, (err) =>{
if (err) { if (err) {
return next(new Error(ErrorCodes.GENERAL_ERROR)); return next(new Error(ErrorCodes.GENERAL_ERROR));
} }
@ -74,11 +73,14 @@ export class UserMWs {
public static listUsers(req:Request, res:Response, next:NextFunction){ public static listUsers(req:Request, res:Response, next:NextFunction){
ObjectManagerRepository.getInstance().getUserManager().find({}, (err, result) =>{ ObjectManagerRepository.getInstance().getUserManager().find({}, (err, result:Array<User>) =>{
if ((err) || (!result)) { if ((err) || (!result)) {
return next(new Error(ErrorCodes.GENERAL_ERROR)); return next(new Error(ErrorCodes.GENERAL_ERROR));
} }
for(let i = 0; i < result.length; i++){
result[i].password = "";
}
req.resultPipe = result; req.resultPipe = result;
return next(); return next();
}); });

View File

@ -40,7 +40,7 @@ export class UserRequestConstrainsMWs {
if(req.session.user.id !== req.params.id){ if(req.session.user.id !== req.params.id){
return next(); return next();
} }
//TODO: fix it!
ObjectManagerRepository.getInstance().getUserManager().find({minRole:UserRoles.Admin}, (err, result) =>{ ObjectManagerRepository.getInstance().getUserManager().find({minRole:UserRoles.Admin}, (err, result) =>{
if ((err) || (!result)) { if ((err) || (!result)) {
return next(new Error(ErrorCodes.GENERAL_ERROR)); return next(new Error(ErrorCodes.GENERAL_ERROR));

View File

@ -1,9 +1,9 @@
import {User} from "../../common/entities/User"; import {User, UserRoles} from "../../common/entities/User";
export interface IUserManager { export interface IUserManager {
findOne(filter,cb:(error: any,result:User) => void); findOne(filter,cb:(error: any,result:User) => void);
find(filter,cb:(error: any,result:Array<User>) => void); find(filter,cb:(error: any,result:Array<User>) => void);
createUser(user,cb:(error: any,result:User) => void); createUser(user,cb:(error: any,result:User) => void);
deleteUser(id:number,cb:(error: any,result:string) => void); deleteUser(id:number,cb:(error: any,result:string) => void);
changeRole(request:any,cb:(error: any) => void); changeRole(id:number, newRole:UserRoles,cb:(error: any) => void);
changePassword(request:any,cb:(error: any,result:string) => void); changePassword(request:any,cb:(error: any,result:string) => void);
} }

View File

@ -1,11 +1,14 @@
import {User} from "../../../common/entities/User"; import {User, UserRoles} from "../../../common/entities/User";
import {IUserManager} from "../IUserManager"; import {IUserManager} from "../IUserManager";
export class UserManager implements IUserManager{ export class UserManager implements IUserManager{
private users = [new User(1,"TestUser","test@test.hu","122345")]; 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[0]); return cb(null, this.users[1]);
} }
public find(filter,cb:(error: any,result:Array<User>) => void){ public find(filter,cb:(error: any,result:Array<User>) => void){
@ -23,8 +26,13 @@ export class UserManager implements IUserManager{
return cb(null); return cb(null);
} }
public changeRole(request:any,cb:(error: any,result:string) => void){ public changeRole(id:number, newRole:UserRoles, cb:(error: any,result:string) => void){
throw new Error("not implemented"); //TODO: implement for(let i = 0; i < this.users.length; i++){
if (this.users[i].id === id){
this.users[i].role = newRole;
return cb(null,"ok");
}
}
} }
public changePassword(request:any,cb:(error: any,result:string) => void){ public changePassword(request:any,cb:(error: any,result:string) => void){
throw new Error("not implemented"); //TODO: implement throw new Error("not implemented"); //TODO: implement

View File

@ -1,44 +1,51 @@
import {User} from "../../../common/entities/User"; import {User, UserRoles} from "../../../common/entities/User";
import {IUserManager} from "../IUserManager"; import {IUserManager} from "../IUserManager";
import {DatabaseManager} from "./DatabaseManager"; import {DatabaseManager} from "./DatabaseManager";
export class MongoUserManager implements IUserManager{ export class MongoUserManager implements IUserManager {
private UserModel; private UserModel;
constructor(){ constructor() {
this.UserModel = DatabaseManager.getInstance().getModel('user',{ this.UserModel = DatabaseManager.getInstance().getModel('user', {
name:String, name: {type: String, index: {unique: true}},
email:{ type: String, index: { unique: true }}, password: String,
password:String, role: Number
role:Number
}); });
} }
public findOne(filter,cb:(error: any,result:User) => void){ public findOne(filter, cb:(error:any, result:User) => void) {
return this.UserModel.findOne(filter,function (err, result) { return this.UserModel.findOne(filter, function (err, result) {
return cb(err, result);
});
}
public find(filter,cb:(error: any,result:Array<User>) => void){
this.UserModel.find(filter,function (err, result) {
return cb(err, result); return cb(err, result);
}); });
} }
public createUser(user,cb:(error: any,result:User) => void){ public find(filter, cb:(error:any, result:Array<User>) => void) {
this.UserModel.create(user,cb); this.UserModel.find(filter, function (err, result) {
return cb(err, result);
});
} }
public deleteUser(id:number,cb:(error: any) => void){ public createUser(user, cb:(error:any, result:User) => void) {
this.UserModel.remove({id:id},cb); this.UserModel.create(user, cb);
} }
public changeRole(request:any,cb:(error: any,result:string) => void){ public deleteUser(id:number, cb:(error:any) => void) {
throw new Error("not implemented"); //TODO: implement this.UserModel.remove({id: id}, cb);
} }
public changePassword(request:any,cb:(error: any,result:string) => void){
public changeRole(id:number, newRole:UserRoles, cb:(error:any, result:string) => void) {
return this.UserModel.update({id: id}, {role: newRole}, function (err) {
if (!err) {
return cb(err, "ok")
}
return cb(err, null);
});
}
public changePassword(request:any, cb:(error:any, result:string) => void) {
throw new Error("not implemented"); //TODO: implement throw new Error("not implemented"); //TODO: implement
} }

View File

@ -66,7 +66,7 @@ export class UserRouter{
private addListUsers() { private addListUsers() {
this.app.post("/api/user/list", this.app.get("/api/user/list",
AuthenticationMWs.authenticate, AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin), AuthenticationMWs.authorise(UserRoles.Admin),
UserMWs.listUsers, UserMWs.listUsers,

View File

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

View File

@ -0,0 +1,11 @@
import {Pipe, PipeTransform} from "angular2/core";
import {UserRoles} from "../../../common/entities/User";
@Pipe({name: 'stringifyRole'})
export class StringifyRole implements PipeTransform {
transform(role: string): number {
return UserRoles[role];
}
}

View File

@ -5,7 +5,38 @@
<h3 class="panel-title">User management</h3> <h3 class="panel-title">User management</h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<button class="btn btn-default" data-toggle="modal" data-target="#myModal" (click)="initNewUser()">+ add
<table class="table table-hover">
<thead>
<tr>
<th>Name</th>
<th>Role</th>
<th></th>
</tr>
</thead>
<tr *ngFor="let user of users">
<td>{{user.name}}</td>
<td *ngIf="canModifyUser(user)">
<select class="form-control" [(ngModel)]="user.role" (ngModelChange)="updateRole(user)" required>
<option *ngFor="let repository of userRoles" [value]="repository.key">
{{repository.value}}
</option>
</select>
</td>
<td *ngIf="!canModifyUser(user)">
{{user.role | stringifyRole}}
</td>
<td>
<button *ngIf="canModifyUser(user)" (click)="deleteUser(user)"
class="btn btn-danger pull-right">
<span class="glyphicon glyphicon-trash" aria-hidden="true" aria-label="Delete"></span>
</button>
</td>
</tr>
</table>
<button class="btn btn-default pull-right" data-toggle="modal" data-target="#myModal"
(click)="initNewUser()">+ Add
user user
</button> </button>
</div> </div>

View File

@ -1,6 +1,6 @@
///<reference path="../../browser.d.ts"/> ///<reference path="../../browser.d.ts"/>
import {Component, OnInit} from "angular2/core"; import {Component, OnInit, Pipe, PipeTransform} from "angular2/core";
import {AuthenticationService} from "../model/network/authentication.service.ts"; import {AuthenticationService} from "../model/network/authentication.service.ts";
import {Router} from "angular2/router"; import {Router} from "angular2/router";
import {FrameComponent} from "../frame/frame.component"; import {FrameComponent} from "../frame/frame.component";
@ -8,21 +8,24 @@ import {User, UserRoles} from "../../../common/entities/User";
import {FORM_DIRECTIVES} from "angular2/common"; import {FORM_DIRECTIVES} from "angular2/common";
import {Utils} from "../../../common/Utils"; import {Utils} from "../../../common/Utils";
import {AdminService} from "./admin.service"; import {AdminService} from "./admin.service";
import {Message} from "../../../common/entities/Message";
import {StringifyRole} from "./StringifyRolePipe";
@Component({ @Component({
selector: 'admin', selector: 'admin',
templateUrl: 'app/admin/admin.component.html', templateUrl: 'app/admin/admin.component.html',
styleUrls: ['app/admin/admin.component.css'], styleUrls: ['app/admin/admin.component.css'],
directives: [FrameComponent, FORM_DIRECTIVES], directives: [FrameComponent, FORM_DIRECTIVES],
providers: [AdminService] providers: [AdminService],
pipes: [StringifyRole]
}) })
export class AdminComponent implements OnInit { export class AdminComponent implements OnInit {
private newUser = new User(); private newUser = new User();
private userRoles:Array<any>; private userRoles:Array<any> = [];
private users:Array<User> = [];
constructor(private _authService:AuthenticationService, private _router:Router, private _adminService:AdminService) { constructor(private _authService:AuthenticationService, private _router:Router, private _adminService:AdminService) {
this.userRoles = Utils.enumToArray(UserRoles);
} }
ngOnInit() { ngOnInit() {
@ -30,15 +33,49 @@ export class AdminComponent implements OnInit {
this._router.navigate(['Login']); this._router.navigate(['Login']);
return; return;
} }
this.userRoles = Utils.enumToArray(UserRoles).filter(r => r.key <= this._authService.getUser().role);
this.getUsersList();
}
private getUsersList(){
this._adminService.getUsers().then((result:Message<Array<User>>) =>{
this.users = result.result;
});
} }
canModifyUser(user:User):boolean{
let currentUser = this._authService.getUser();
if(!currentUser){
return false;
}
return currentUser.name != user.name && currentUser.role >= user.role;
}
initNewUser() { initNewUser() {
this.newUser = new User(); this.newUser = new User();
this.newUser.role = UserRoles.User; this.newUser.role = UserRoles.User;
} }
addNewUser(){ addNewUser(){
this._adminService.createUser(this.newUser); this._adminService.createUser(this.newUser).then(() =>{
this.getUsersList();
});
}
updateRole(user:User){
this._adminService.updateRole(user).then(() =>{
this.getUsersList();
});
}
deleteUser(user:User){
this._adminService.deleteUser(user).then(() =>{
this.getUsersList();
});
} }
} }

View File

@ -19,7 +19,16 @@ export class AdminService extends NetworkService{
} }
public getUsers():Promise<Message<Array<User>>>{
return this.getJson("/user/list");
}
public deleteUser(user:User) {
return this.deleteJson("/user/"+user.id);
}
public updateRole(user:User) {
return this.postJson("/user/"+user.id+"/role",{newRole:user.role});
}
} }

View File

@ -88,9 +88,7 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit{
private getContainerWidth(): number{ private getContainerWidth(): number{
if(!this.gridContainer){ if(!this.gridContainer){
return 0; return 0;
} }
console.log(this.gridContainer);
console.log(this.gridContainer.nativeElement.clientWidth);
return this.gridContainer.nativeElement.clientWidth; return this.gridContainer.nativeElement.clientWidth;
} }

View File

@ -20,7 +20,7 @@ export class LoginComponent implements OnInit{
ngOnInit(){ ngOnInit(){
if (this._authService.isAuthenticated()) { if (this._authService.isAuthenticated()) {
this._router.navigate(['Gallery']); this._router.navigate(['Gallery',{directory:"/"}]);
} }
} }

View File

@ -17,7 +17,7 @@ export class NetworkService{
let headers = new Headers({ 'Content-Type': 'application/json' }); let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers }); let options = new RequestOptions({ headers: headers });
if(method == "get"){ if(method == "get" || method == "delete"){
return this._http[method](this._baseUrl+url, options) return this._http[method](this._baseUrl+url, options)
.toPromise() .toPromise()
.then(res => <Message<any>> res.json()) .then(res => <Message<any>> res.json())