Permalink
Browse files

Adding a new Auth module

  • Loading branch information...
1 parent 8d9aca8 commit 8dbdfeccda1f3574b901d1467b53cc1a3daadddf Dean Sofer committed Sep 12, 2012
Showing with 126 additions and 0 deletions.
  1. +82 −0 modules/auth/auth.js
  2. +44 −0 modules/auth/test/authSpec.js
View
@@ -0,0 +1,82 @@
+/**
+ * @license HTTP Auth Interceptor Module for AngularJS
+ * (c) 2012 Witold Szczerba
+ * License: MIT
+ */
+angular.module('ui.auth', ['ui.config'])
+
+ .provider('uiAuth', ['ui.config', function(uiConfig) {
+ uiConfig.auth = uiConfig.auth || {};
+ /**
+ * Holds all the requests which failed due to 401 response,
+ * so they can be re-requested in future, once login is completed.
+ */
+ var buffer = [];
+
+ /**
+ * Required by HTTP interceptor.
+ * Function is attached to provider to be invisible for regular users of this service.
+ */
+ this.pushToBuffer = function(config, deferred) {
+ buffer.push({
+ config: config,
+ deferred: deferred
+ });
+ }
+
+ this.$get = ['$rootScope','$injector', function($rootScope, $injector) {
+ var $http; //initialized later because of circular dependency problem
+ function retry(config, deferred) {
+ $http = $http || $injector.get('$http');
+ $http(config).then(function(response) {
+ deferred.resolve(response);
+ });
+ }
+ function retryAll() {
+ angular.forEach(buffer, function(item){
+ retry(item.config, item.deferred);
+ });
+ buffer = [];
+ }
+
+ return {
+ authenticated: function(resetBuffer) {
+ $rootScope.$broadcast('ui:authenticated');
+ if (resetBuffer === undefined && uiConfig.auth.resetBuffer)
+ buffer = [];
+ else
+ retryAll();
+ }
+ }
+ }]
+ })
+
+ /**
+ * $http interceptor.
+ * On 401 response - it stores the request and broadcasts 'ui:unauthenticated'.
+ */
+ .config(['$httpProvider', 'uiAuthProvider', function($httpProvider, uiAuthProvider) {
+
+ var interceptor = ['$rootScope', '$q', function($rootScope, $q) {
+ function success(response) {
+ return response;
+ }
+
+ function error(response) {
+ if (response.status === 401) {
+ var deferred = $q.defer();
+ authProvider.pushToBuffer(response.config, deferred);
+ $rootScope.$broadcast('ui:unauthenticated');
+ return deferred.promise;
+ }
+ // otherwise
+ return $q.reject(response);
+ }
+
+ return function(promise) {
+ return promise.then(success, error);
+ }
+
+ }];
+ $httpProvider.responseInterceptors.push(interceptor);
+ }]);
@@ -0,0 +1,44 @@
+/*
+ * sample unit testing for sample templates and implementations
+ */
+describe('uiAuth', function () {
+
+ // declare these up here to be global to all tests
+ var $rootScope, uiConfig = angular.module('ui.config');
+
+ beforeEach(module('ui.auth'));
+
+ // inject in angular constructs. Injector knows about leading/trailing underscores and does the right thing
+ // otherwise, you would need to inject these into each test
+ beforeEach(inject(function (_$rootScope_, _$http_, _$httpBackend_) {
+ $rootScope = _$rootScope_;
+ $http = _$http_;
+ $httpBackend = _$httpBackend_;
+
+ // backend definition common for all tests
+ $httpBackend.when('POST', '/login').respond(200, '');
+ }));
+
+ afterEach(function () {
+ uiConfig.value('ui.config', {});
+ $httpBackend.verifyNoOutstandingExpectation();
+ $httpBackend.verifyNoOutstandingRequest();
+ });
+
+ it('should emit unauthenticated if 401 returned', function () {
+ expect(false).toBeTruthy();
+ });
+
+ describe('authenticated()', function() {
+ it('should emit "ui:authenticated"', function () {
+ expect(false).toBeTruthy();
+ });
+ it('should retry all buffered requests', function () {
+ expect(false).toBeTruthy();
+ });
+ it('should ignore buferred requests when passing true', function () {
+ expect(false).toBeTruthy();
+ });
+ });
+
+});

0 comments on commit 8dbdfec

Please sign in to comment.