happstack-authenticate-2.1.3: Happstack/Authenticate/OpenId/Controllers.hs
{-# LANGUAGE QuasiQuotes, OverloadedStrings #-}
module Happstack.Authenticate.OpenId.Controllers where
import Control.Lens ((^.))
import Control.Monad.Trans (MonadIO(..))
import Data.Acid (AcidState)
import Data.Acid.Advanced (query')
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import qualified Data.Text as T
import Happstack.Authenticate.Core (AuthenticateState, AuthenticateURL, getToken, tokenIsAuthAdmin)
import Happstack.Authenticate.OpenId.Core (GetOpenIdRealm(..), OpenIdState)
import Happstack.Authenticate.OpenId.URL (OpenIdURL(BeginDance, Partial, ReturnTo), nestOpenIdURL)
import Happstack.Authenticate.OpenId.PartialsURL (PartialURL(UsingGoogle, UsingYahoo, RealmForm))
import Happstack.Server (Happstack)
import Language.Javascript.JMacro
import Web.Routes
openIdCtrl
:: (Happstack m) =>
AcidState AuthenticateState
-> AcidState OpenIdState
-> RouteT AuthenticateURL m JStat
openIdCtrl authenticateState openIdState =
nestOpenIdURL $
do fn <- askRouteFn
mt <- getToken authenticateState
mRealm <- case mt of
(Just (token, _))
| token ^. tokenIsAuthAdmin ->
query' openIdState GetOpenIdRealm
| otherwise -> return Nothing
Nothing -> return Nothing
return $ openIdCtrlJs mRealm fn
openIdCtrlJs
:: Maybe Text
-> (OpenIdURL -> [(Text, Maybe Text)] -> Text)
-> JStat
openIdCtrlJs mRealm showURL =
[jmacro|
var openId = angular.module('openId', ['happstackAuthentication']);
var openIdWindow;
tokenCB = function (token) { alert('tokenCB: ' + token); };
openId.controller('OpenIdCtrl', ['$scope','$http','$window', '$location', 'userService', function ($scope, $http, $window, $location, userService) {
$scope.openIdRealm = { srOpenIdRealm: `(fromMaybe "" mRealm)` };
// $scope.isAuthenticated = userService.getUser().isAuthenticated;
// $scope.$watch(function () { return userService.getUser().isAuthenticated; }, function(newVal, oldVal) { $scope.isAuthenticated = newVal; });
$scope.openIdWindow = function (providerUrl) {
// openIdWindow = window.open(`(showURL ReturnTo [])`, "_blank", "toolbar=0");
tokenCB = function(token) { var u = userService.updateFromToken(token); $scope.isAuthenticated = u.isAuthenticated; $scope.$apply(); };
openIdWindow = window.open(providerUrl, "_blank", "toolbar=0");
};
$scope.setOpenIdRealm = function (setRealmUrl) {
$http.post(setRealmUrl, $scope.openIdRealm).
success(function(datum, status, headers,config) {
$scope.set_openid_realm_msg = 'Realm Updated.'; // FIXME -- I18N
}).
error(function (datum, status, headers, config) {
$scope.set_openid_realm_msg = datum.error;
})};
}]);
openId.directive('openidGoogle', ['$rootScope', function ($rootScope) {
return {
restrict: 'E',
replace: true,
templateUrl: `(showURL (Partial UsingGoogle) [])`
};
}]);
openId.directive('openidYahoo', ['$rootScope', function ($rootScope) {
return {
restrict: 'E',
replace: true,
templateUrl: `(showURL (Partial UsingYahoo) [])`
};
}]);
openId.directive('openidRealm', ['$rootScope', function ($rootScope) {
return {
restrict: 'E',
templateUrl: `(showURL (Partial RealmForm) [])`
};
}]);
|]
{-
openIdCtrlJs showURL = [jmacro|
{
//this is used to parse the profile
function url_base64_decode(str) {
var output = str.replace('-', '+').replace('_', '/');
switch (output.length % 4) {
case 0:
break;
case 2:
output += '==';
break;
case 3:
output += '=';
break;
default:
throw 'Illegal base64url string!';
}
return window.atob(output); //polifyll https://github.com/davidchambers/Base64.js
}
var happstackAuthentication = angular.module('happstackAuthentication', []);
happstackAuthentication.factory('userService', ['$rootScope', function ($rootScope) {
var defaultUser = { isAuthenticated: false,
username: '<unset>',
token: null
};
var service = {
userCache: defaultUser,
setUser: function(u) {
// alert('setUser:' + JSON.stringify(u));
userCache = u;
localStorage.setItem('user', JSON.stringify(u));
},
getUser: function() {
var item = localStorage.getItem('user');
if (item) {
// alert('getUser: ' + item);
var user = JSON.parse(item);
return(user);
}
},
clearUser: function () {
userCache = defaultUser;
this.setUser(defaultUser);
}
};
if (!localStorage.getItem('user')) {
service.clearUser();
}
return service;
}]);
var openId = angular.module('openId', ['happstackAuthentication']);
openId.controller('UsernamePasswordCtrl', ['$scope','$http','$window', '$location', 'userService', function ($scope, $http, $window, $location, userService) {
$scope.isAuthenticated = userService.getUser().isAuthenticated;
$scope.login = function () {
$http.
post(`(showURL Token [])`, $scope.user).
success(function (datum, status, headers, config) {
var encodedClaims = datum.token.split('.')[1];
var claims = JSON.parse(url_base64_decode(encodedClaims));
$scope.username_password_error = '';
var u = userService.getUser();
u.isAuthenticated = true;
$scope.isAuthenticated = true;
u.username = $scope.user.user; // FIXME: this should come from the token
u.token = datum.token;
userService.setUser(u);
}).
error(function (datum, status, headers, config) {
// Erase the token if the user fails to log in
userService.clearUser();
$scope.isAuthenticated = false;
// Handle login errors here
$scope.username_password_error = datum.error;
});
};
$scope.logout = function () {
userService.clearUser();
$scope.isAuthenticated = false;
};
$scope.signupPassword = function () {
$scope.signup.naUser.userId = 0;
$http.
post(`(showURL (Account Nothing) [])`, $scope.signup).
success(function (datum, status, headers, config) {
$scope.signup_error = 'Account Created'; // FIXME -- I18N
$scope.signup = {};
}).
error(function (datum, status, headers, config) {
$scope.signup_error = datum.error;
});
};
$scope.changePassword = function (url) {
var u = userService.getUser();
if (u.isAuthenticated) {
$http.
post(url, $scope.password).
success(function (datum, status, headers, config) {
$scope.change_password_error = 'Password Changed.'; // FIXME -- I18N
$scope.password = {};
}).
error(function (datum, status, headers, config) {
$scope.change_password_error = datum.error;
});
} else {
$scope.change_password_error = 'Not Authenticated.'; // FIXME -- I18N
}
};
$scope.requestResetPassword = function () {
$http.post(`(showURL PasswordRequestReset [])`, $scope.requestReset).
success(function (datum, status, headers, config) {
$scope.request_reset_password_msg = datum;
}).
error(function (datum, status, headers, config) {
$scope.request_reset_password_msg = datum.error;
});
};
$scope.resetPassword = function () {
var resetToken = $location.search().reset_token;
if (resetToken) {
$scope.reset.rpResetToken = resetToken;
$http.post(`(showURL PasswordReset [])`, $scope.reset).
success(function (datum, status, headers, config) {
$scope.reset_password_msg = datum;
}).
error(function (datum, status, headers, config) {
$scope.reset_password_msg = datum.error;
});
} else {
$scope.reset_password_msg = "reset token not found."; // FIXME -- I18N
}
};
}]);
openId.factory('authInterceptor', ['$rootScope', '$q', '$window', 'userService', function ($rootScope, $q, $window, userService) {
return {
request: function (config) {
config.headers = config.headers || {};
u = userService.getUser();
if (u && u.token) {
config.headers.Authorization = 'Bearer ' + u.token;
}
return config;
},
responseError: function (rejection) {
if (rejection.status === 401) {
// handle the case where the user is not authenticated
}
return $q.reject(rejection);
}
};
}]);
openId.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
}]);
// upAuthenticated directive
openId.directive('upAuthenticated', ['$rootScope', 'userService', function ($rootScope, userService) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var prevDisp = element.css('display');
$rootScope.$watch(function () { return userService.getUser().isAuthenticated; },
function(auth) {
if (auth != (attrs.upAuthenticated == 'true')) {
element.css('display', 'none');
} else {
element.css('display', prevDisp);
}
});
}
};
}]);
// upLoginInline directive
openId.directive('upLoginInline', ['$rootScope', 'userService', function ($rootScope, userService) {
return {
restrict: 'E',
// replace: true,
templateUrl: `(showURL (Partial LoginInline) [])`
};
}]);
// upChangePassword directive
openId.directive('upChangePassword', ['$rootScope', '$http', '$compile', 'userService', function ($rootScope, $http, $compile, userService) {
function link(scope, element, attrs) {
$rootScope.$watch(function() { return userService.getUser().isAuthenticated; },
function(auth) {
if (auth == true) {
$http.get(`(showURL (Partial ChangePassword) [])`).
success(function(datum, status, headers, config) {
element.empty();
var newElem = angular.element(datum);
element.append(newElem);
$compile(newElem)(scope);
});
} else {
element.empty();
}
});
}
return {
restrict: 'E',
link: link
// templateUrl: `(showURL (Partial ChangePassword) [])`
// template: "<div ng-include=\"'" + `(showURL (Partial ChangePassword) [])` + "'\"></div>"
// template: "<div ng-include=\"'/authenticate/authentication-methods/password/partial/change-password'\"></div>"
};
/*
return {
restrict: 'E',
templateUrl: `(showURL (Partial ChangePassword) [])`
};
*/
}]);
// upRequestResetPassword directive
openId.directive('upRequestResetPassword', [function () {
return {
restrict: 'E',
// replace: true,
templateUrl: `(showURL (Partial RequestResetPasswordForm) [])`
};
}]);
// upResetPassword directive
openId.directive('upResetPassword', [function () {
return {
restrict: 'E',
// replace: true,
templateUrl: `(showURL (Partial ResetPasswordForm) [])`
};
}]);
openId.directive('upSignupPassword', [function () {
return {
restrict: 'E',
// replace: true,
templateUrl: `(showURL (Partial SignupPassword) [])`
};
}]);
}
|]
-}