(function() { 'use strict'; var appRoutes = [{ title: "Login", url: "/", templateUrl: "views/main.html", controller:null, controllerAs: null, requiredAuth: false, show: true, icon: 'fa-home' }, { title: "Claims", //todo-auth add claims module url: "/claims", templateUrl: "views/claims.html", controller: "app.ctrl.claims", controllerAs: "ctrl", redirectTo: '/noaccess', claims: "app.claims", requiredAuth: true, show: true, icon:'fa-key' }, { title: "No Access", url: "/noaccess", templateUrl: "views/noaccess.html", controller: null, controllerAs: null, requiredAuth: false }]; var app = angular.module('app', ['ngRoute']); app.constant('$appRoutes', appRoutes) app.config(['$routeProvider', '$appRoutes', appConfig]); app.run(['$rootScope', '$location', runApp]); app.factory('app.svc.auth', [svcAuth]); app.controller('app.ctrl.claims', ['app.svc.auth','$scope', ctrlClaims]); app.controller('app.ctrl.menu', ['$appRoutes',ctrlMenu]); app.directive("authorize", ['app.svc.auth', dirAuthorize]); function appConfig($routeProvider, $appRoutes) { $appRoutes.forEach(function (route) { configRoute(route); function configRoute(route) { $routeProvider .when(route.url, { templateUrl: route.templateUrl, controller: route.controller, controllerAs: route.controllerAs, resolve: { //todo-auth secure routes "hasClaim": ["app.svc.auth", "$route", function ($svcAuth, $route) { var result = false; if (route.requiredAuth) { var result = $svcAuth.hasClaim(route.claims); if (!result) { $route.current.noAccess = route.redirectTo; throw new Error('No access to route: ' + route.url); } else { $route.current.noAccess = null; } } return result; }] } }); } }); $routeProvider.otherwise("/"); } function svcAuth() { //simple claims container for demo purposes var claims = { 'Name': 'Ozkary', 'app.delete': true, 'app.edit': true,'app.claims':true }; function hasClaim(key) { return claims[key];//todo handle multiple claims } return { claims: claims, hasClaim:hasClaim }; } function runApp($rootScope, $location) { $rootScope.$on('$routeChangeError', function (evt, current, previous, reject) { $location.path(current.noAccess); console.log(reject.message); }); } function ctrlClaims($svcAuth, $scope) { var ctrl = this; //var storage = angular.copy($svcAuth.claims); ctrl.claims = $svcAuth.claims; ctrl.edit = function(key) { if (ctrl.selected === key) { ctrl.selected = null; } else { ctrl.selected = key; } } ctrl.remove = function(key){ delete ctrl.claims[key]; } } function ctrlMenu($appRoutes) { var ctrl = this; ctrl.menu = $appRoutes; } function dirAuthorize($svcAuth) { return { restrict: 'A', scope: { authorize: '=' }, link: function (scope, elem, attrs) { var watch = function () { //get the claim value var claims = scope.authorize; if (claims) { var result = $svcAuth.hasClaim(claims); if (!result) { elem.hide(); } } }; scope.$watch(watch); } }; }; })();
<div ng-app="app"> <div id="container" > <div id="page-wrapper"> <nav class="navbar navbar-default" role="navigation"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#app-menu"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Route Claims Authorization by ozkary.com</a> </div> <div class="collapsed navbar-collapse" id="app-menu"> <ul class="nav navbar-nav" ng-controller="app.ctrl.menu as ctrl"> <li ng-repeat="item in ctrl.menu"> <a authorize="item.claims" href="#{{item.url}}" ng-show="item.show"><i class="fa {{item.icon}}"></i> <span ng-bind="item.title"></span></a> </li> </ul> </div> </nav> <section class="container"> <ng-view /> </section> </div> <!-- /#page-wrapper --> </div> <script type="text/ng-template" id="views/main.html"> <div class="view"> <div class="panel panel-default"> <div class="panel-heading"> Please Login </div> <div class="panel-body text-center"> <div class="row" > <i class="fa fa-lock fa-5x"></i><br> <form class="form form-signin" name="frmLogin" novalidate> <h2 class="form-signin-heading">Please Sign in</h2> <label for="inputEmail" class="sr-only">Email</label> <input type="email" id="inputEmail" ng-model="user.username" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" id="inputPassword" ng-model="user.password" class="form-control" placeholder="Password" required ng-minlength="6" ng-maxlength="6"> <div></div> <button class="btn btn-primary" ng-click="login()" type="button" ng-disabled="frmLogin.$invalid">Sign in <i class="fa fa-sign-in"></i></button> </form> </div> </div> <div class="panel-footer"> @ ozkary.com </div> </div> </script> <script type="text/ng-template" id="views/claims.html" > <div class="row" > <div class="col-lg-12"> <div class="panel panel-default"> <div class="panel-heading"> My Claims </div> <!-- /.panel-heading --> <div class="panel-body text-center"> <ul class="list-group text-left"> <li ng-repeat="(key,value) in ctrl.claims" class="list-group-item"> <label style="width:150px;">{{key}}</label> <input type="text" class="form-control-static form-input" maxlength="25" ng-disabled="key !== ctrl.selected" ng-model="ctrl.claims[key]" /> <span class="pull-right"> <a class="cursor-pointer" title="remove claim" ng-click="ctrl.remove(key)"><i class="fa fa-trash text-danger fa-2x"></i></a> <a class="cursor-pointer" title="edit claim" ng-click="ctrl.edit(key)"><i class="fa fa-edit fa-2x"></i></a> </span> </li> </ul> </div> <!-- /.panel-body --> <div class="panel-footer"> </div> </div> <!-- /.panel --> </div> <!-- /.col-lg-6 --> </div> <!-- /.row --> </script> <script type="text/ng-template" id="views/noaccess.html"> <div class="row"> <div class="col-lg-12"> <div class="panel panel-default"> <div class="panel-heading">Access Denied</div> <!-- /.panel-heading --> <div class="panel-body text-center"> <i class="fa fa-ban fa-5x text-danger"></i> <h3>This area has not been shared with you.</h3> </div> <!-- /.panel-body --> <div class="panel-footer"> </div> </div> <!-- /.panel --> </div> </div> </script> <br/>