0

I want to develop a component in my angular 4 application which mange the menu in the dashboard of my app.

My problem is that i have different type of users ('admin', 'expert', 'manager', ...) and for each user there is a list of items that should appear in the menu so each user has a different menu.

After some researches I found a the ngx-permissions library which manage Permission and roles

Can any one gives me the approach or the logic to follow to build the menu component, in other words, how to proceed to handle permissons in the menu component

Wassim Makni
  • 471
  • 2
  • 9
  • 21
  • Are there common menu items for these users? A simple approach would also be to maintain a list of menu items for each type of user and a common list and populate the menu with these lists. You can also write a function which returns whether a particular item should appear on the menu for a particular user. – Salander Oct 03 '17 at 11:30
  • have you tried with AuthGuard and RoleGuard of Angular4? – federico scamuzzi Oct 03 '17 at 11:32
  • @Salander yes i agree with you but this is a classic approach, i mean is there any library for exemple to do the work ? – Wassim Makni Oct 03 '17 at 11:41
  • @federicoscamuzzi yes i thought about that but i didn' t find a tutorial which is similar to my requirement. – Wassim Makni Oct 03 '17 at 11:44

1 Answers1

1

what you can try to do is to create a ts file like:

AsnetUserDTO .ts file

export class AspNetUsersDTO extends EntityBase {

    constructor(values: Object = {}) {
        super();
        Object.assign(this, values);
    }


    public firstName: string;
    public fullName: string;
    public lastName: string;
    public userName: string;
    public securityStamp: string;
    public email: string;
    public emailConfirmed: boolean;
    public phoneNumber: string;
    public phoneNumberConfirmed: boolean;
    public twoFactorEnabled: boolean;
    public lockoutEndDateUtc: any;
    public lockoutEnabled: boolean;
    public accessFailedCount: number;
    public roles: string[];
    public passwordHash: string;
    public logins: any[];
    public claims: any[];

    public imageProfile: string;
    public thumbImageProfile: string;
    public primaryColor: string;

}

ROLEGUARD.ts file:

import { Injectable } from "@angular/core";
import { AuthService, CurrentUserService } from "app/shared/services";
import { Router, RouterStateSnapshot, ActivatedRouteSnapshot, CanActivate } from "@angular/router";
import { AspNetUsersDTO } from "app/shared/models";
import { Observable } from "rxjs/Rx";

@Injectable()
export class RoleGuard implements CanActivate {

    constructor(private authService: AuthService,
        private _currentUser: CurrentUserService,
        private router: Router) {
    }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
        return new Promise<boolean>((resolve, reject) => {

            if (!this.authService.isLoggedIn()) {
                resolve(false);
                this.router.navigate(['login']);
                return;
            }


            var currentUser: AspNetUsersDTO = new AspNetUsersDTO();

            this._currentUser.GetCurrentUser().then((resp) => {
                currentUser = resp;
                let userRole = currentUser.roles && currentUser.roles.length > 0 ? currentUser.roles[0].toUpperCase() : '';
                let roles = route && route.data["roles"] && route.data["roles"].length > 0 ? route.data["roles"].map(xx => xx.toUpperCase()) : null;

                if (roles == null || roles.indexOf(userRole) != -1) resolve(true);
                else {
                    resolve(false);
                    this.router.navigate(['login']);
                }

            }).catch((err) => {
                reject(err);
                this.router.navigate(['login']);
            });
        });

    }

    canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {

        return new Promise<boolean>((resolve, reject) => {

            if (!this.authService.isLoggedIn()) {
                resolve(false);
                this.router.navigate(['login']);
                return;
            }


            var currentUser: AspNetUsersDTO = new AspNetUsersDTO();

            this._currentUser.GetCurrentUser().then((resp) => {
                currentUser = resp;
                let userRole = currentUser.roles && currentUser.roles.length > 0 ? currentUser.roles[0].toUpperCase() : '';
                let roles = route && route.data["roles"] && route.data["roles"].length > 0 ? route.data["roles"].map(xx => xx.toUpperCase()) : null;

                if (roles == null || roles.indexOf(userRole) != -1) resolve(true);
                else {
                    resolve(false);
                    this.router.navigate(['login']);
                }

            }).catch((err) => {
                reject(err);
                this.router.navigate(['login']);
            });
        });

    }
}

then you can you use it in your routing file like (app.routing.ts):

{
        path: 'awards-team',
        component: AwardsTeamComponent,
        canActivateChild: [RoleGuard], // for child route you pass before in RoleGuad file and it check if roles are the same as your current user
        children: [
          {
            path: 'admin',

            component: TeamComponentsComponent,
            data: { roles: ['super-admin', 'admin'] }
          },
          {
            path: 'user',
            component: TeamComponentsComponent
          }
        ]
      }

hope it help you

federico scamuzzi
  • 3,708
  • 1
  • 17
  • 24