Lorenzo
Lorenzo

Reputation: 197

Angular guard true/false depending on permission

I have 4 routes where each one will have a permission linked to it (provided by the backend -> true/false). These permissions give a logged-in user the authorization to access particular routes.

Now my question is if it is possible to make only one guard which checks all of the linked permissions, but only blocks the particular route where the linked permission is 'false'?

Example (4 features, with 4 permissions):

permissions: {
  permission_1": false, // matches /post/create
  permission_2": false, // matches /admin/post
  permission_3": false, // matches /admin/delete
  permission_4": true, // matches /subscribe
}

The guard checks only the matching permission for the particular route. In other words, the user will only have access to the "/subscribe" route and not for the other three.

Upvotes: 0

Views: 3704

Answers (2)

Alexis Zapata
Alexis Zapata

Reputation: 1023

First you need to create an HTTP request, which gets json with the url and its value, like this.

 {
   home: true,
   rotue1:false
 }

Create a service that implements the canActivate interface

@Injectable({
    providedIn: 'root'
})
export class EnabledUrlService implements CanActivate {

    constructor(private router: Router) {
    }

     canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
        return this.authService.getPermissions()
            .pipe(map((resoruce: any) => resource[route.data?.id])
     }
}

And include this service in the routing file

        {
            path: 'rotue1',
            component: RouteComponent,
            canActivate: [EnabledUrlService]
        },
        {
            path: 'home',
            component: HomeComponent,
            canActivate: [EnabledUrlService]
        }

I hope help you, if have any questions, let me know

Upvotes: 1

cklimowski
cklimowski

Reputation: 601

Yes, you can do this with one Guard. You can use CanActivate or CanActivateChild as needed.

// Angular imports
import {
  CanActivate,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
  UrlTree,
  Router,
} from "@angular/router";

@Injectable({
  providedIn: "root",
})

export class PermGuard implements CanActivate, OnDestroy {
  constructor(private router: Router) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
      const url: string = state.url;
      return this.checkPerms(url);
    }

  checkPerms(url: string): | Observable<boolean | UrlTree>| Promise<boolean | UrlTree> | boolean | UrlTree {
    // Check for Perms compared to URL that the app is routing to here.
    if (url.includes("create") {
      //check for perms for "create" url here...
    }
  }

Upvotes: 1

Related Questions