Skip to content

Commit

Permalink
Added a box to show the current user and a logout button.
Browse files Browse the repository at this point in the history
  • Loading branch information
petebacondarwin committed Oct 1, 2012
1 parent 4ded5a9 commit 628c826
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 15 deletions.
11 changes: 6 additions & 5 deletions src/app/signin/form.tpl.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<div class="row-fluid" ng-controller="SignInCtrl" ng-show="authService.isLoginRequired()">
<div class="span4 offset4 well">
<div class="row-fluid" ng-controller="SignInCtrl" >
<div class="span4 offset4 well" ng-show="authService.currentUser">
You are logged in as: {{authService.currentUser.firstName}} {{authService.currentUser.lastName}}
<button ng-click="authService.logout()">Logout</button>
</div>
<div class="span4 offset4 well" ng-show="authService.isLoginRequired()">
<h4>Sign in</h4>
<hr>
<div class="alert alert-error" ng-show="authError">
Expand All @@ -16,6 +20,3 @@ <h4>Sign in</h4>
<button class="btn" ng-click="clearForm()">Clear</button>
</div>
</div>
<div ng-hide="authService.isLoginRequired()">
Current User: {{authService.currentUser | json}}
</div>
8 changes: 6 additions & 2 deletions src/app/signin/signin.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
angular.module('signin', ['services.authentication','services.users']).controller('SignInCtrl', ['$scope', 'AuthenticationService', function ($scope, AuthenticationService) {
angular.module('signin', ['services.authentication', 'services.users']).controller('SignInCtrl', ['$scope', 'AuthenticationService', function($scope, AuthenticationService) {

$scope.user = {};
$scope.authError = false;
$scope.authService = AuthenticationService;

$scope.clearForm = function () {
$scope.clearForm = function() {
$scope.user = {};
};

// Get the current user when the controller is instantiated - this could be put in the main app controller so that it is only called once??
AuthenticationService.requestCurrentUser();

}]);
28 changes: 22 additions & 6 deletions src/common/services/authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ angular.module('services.authentication', []);
// The AuthenticationService is the public API for this module. Application developers should only need to use this service and not any of the others here.
// The general idea is that you watch isLoginRequired for a change to true. This happens when a http request returns 401 unauthorized. When this happens you need to show your login dialog box.
// When the user has successfully logged in you call loginConfirmed to retry any queued requests.
angular.module('services.authentication').factory('AuthenticationService', ['$rootScope', '$http', 'AuthenticationRequestRetryQueue', function($rootScope, $http, queue) {
angular.module('services.authentication').factory('AuthenticationService', ['$http', 'AuthenticationRequestRetryQueue', function($http, queue) {

function retryRequest (next) {
$http(next.request).then(function(response) {
Expand All @@ -28,11 +28,18 @@ angular.module('services.authentication').factory('AuthenticationService', ['$ro
// Login to the back end - on success will trigger
login: function(email, password) {
var request = $http.post('/login', {email: email, password: password});
request.success(function(response) {
return request.then(function(response) {
service.retryRequests();
service.requestCurrentUser();
return service.requestCurrentUser();
});
},

logout: function() {
$http.post('/logout').then(function() {
service.currentUser = null;
// TODO: We need a way to refresh the page to clear any data that has been loaded when the user logs out
// a simple way would be to redirect to the root of the application but this feels a bit inflexible.
});
return request;
},

// Retry the requests once the user has successfully logged in
Expand All @@ -45,15 +52,22 @@ angular.module('services.authentication').factory('AuthenticationService', ['$ro
// Ask the backend to see if a users is already authenticated - this may be from a previous session.
// The app should probably do this at start up
requestCurrentUser: function() {
return $http.get('/current-user').success(function(response) {
service.currentUser = response;
return $http.get('/current-user').then(function(response) {
service.currentUser = response.data;
});
}
};

return service;
}]);


// The main reason for this service is to decouple the AuthenticationService and the AuthenticationInterceptor.
// Otherwise you get circular dependencies based around $http:
// - AuthenticationService -> $http -> AuthenticationInterceptor -> AuthenticationService
// In this case we have:
// - AuthenticationService -> [AuthenticationRequestRetryQueue, $http]
// - $http -> AuthenticationInterceptor -> AuthenticationRequestRetryQueue
angular.module('services.authentication').factory('AuthenticationRequestRetryQueue', ['$q', function($q) {
var retryQueue = [];
return {
Expand All @@ -72,6 +86,7 @@ angular.module('services.authentication').factory('AuthenticationRequestRetryQue
};
}]);

// Simply intercept the request and add it to the retry queue if it is unauthorized
angular.module('services.authentication').factory('AuthenticationInterceptor', ['AuthenticationRequestRetryQueue', function(queue) {
return function(promise) {
return promise.then(null, function(response) {
Expand All @@ -83,6 +98,7 @@ angular.module('services.authentication').factory('AuthenticationInterceptor', [
};
}]);

// We have to add the interceptor to the queue as a string because the interceptor depends upon service instances that are not available in the config block.
angular.module('services.authentication').config(['$httpProvider', function($httpProvider) {
$httpProvider.responseInterceptors.push('AuthenticationInterceptor');
}]);
4 changes: 2 additions & 2 deletions test/unit/common/services/authenticationSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ describe('services.authentication', function() {
var userInfo = { email: '[email protected]', firstName: 'Jo', lastName: 'Bloggs'};
$httpBackend.expect('GET', '/current-user');
$httpBackend.when('GET', '/current-user').respond(userInfo);
service.requestCurrentUser().success(function(response) {
expect(response).toBe(userInfo);
service.requestCurrentUser().then(function(response) {
expect(service.currentUser).toBe(userInfo);
});
$httpBackend.flush();
});
Expand Down

0 comments on commit 628c826

Please sign in to comment.