/** * Service which monitors the current user session and provides methods for returning information * about the user. */ angular.module('quay') .factory('UserService', ['ApiService', 'CookieService', '$rootScope', 'Config', '$location', function(ApiService, CookieService, $rootScope, Config, $location) { var userResponse = { verified: false, anonymous: true, username: null, email: null, organizations: [], logins: [], beforeload: true } var userService = {} var _EXTERNAL_SERVICES = ['ldap', 'jwtauthn', 'keystone', 'dex']; userService.hasEverLoggedIn = function() { return CookieService.get('quay.loggedin') == 'true'; }; userService.updateUserIn = function(scope, opt_callback) { scope.$watch(function () { return userService.currentUser(); }, function (currentUser) { scope.user = currentUser; if (opt_callback) { opt_callback(currentUser); } }, true); }; userService.load = function(opt_callback) { var handleUserResponse = function(loadedUser) { userResponse = loadedUser; if (!userResponse.anonymous) { if (Config.MIXPANEL_KEY) { try { mixpanel.identify(userResponse.username); mixpanel.people.set({ '$email': userResponse.email, '$username': userResponse.username, 'verified': userResponse.verified }); mixpanel.people.set_once({ '$created': new Date() }) } catch (e) { window.console.log(e); } } if (Config.MARKETO_MUNCHKIN_ID && userResponse['marketo_user_hash']) { associateLeadBody = {'Email': userResponse.email}; if (window.Munchkin !== undefined) { try { Munchkin.munchkinFunction( 'associateLead', associateLeadBody, userResponse['marketo_user_hash'] ); } catch (e) { } } else { window.__quay_munchkin_queue.push([ 'associateLead', associateLeadBody, userResponse['marketo_user_hash'] ]); } } if (window.Raven !== undefined) { try { Raven.setUser({ email: userResponse.email, id: userResponse.username }); } catch (e) { window.console.log(e); } } CookieService.putPermanent('quay.loggedin', 'true'); } else { if (window.Raven !== undefined) { Raven.setUser(); } } // If the loaded user has a prompt, redirect them to the update page. if (loadedUser.prompts && loadedUser.prompts.length) { $location.path('/updateuser'); return; } if (opt_callback) { opt_callback(loadedUser); } }; ApiService.getLoggedInUser().then(function(loadedUser) { handleUserResponse(loadedUser); }, function() { handleUserResponse({'anonymous': true}); }); }; userService.isOrganization = function(name) { return !!userService.getOrganization(name); }; userService.getOrganization = function(name) { if (!userResponse || !userResponse.organizations) { return null; } for (var i = 0; i < userResponse.organizations.length; ++i) { var org = userResponse.organizations[i]; if (org.name == name) { return org; } } return null; }; userService.isNamespaceAdmin = function(namespace) { if (namespace == userResponse.username) { return true; } var org = userService.getOrganization(namespace); if (!org) { return false; } return org.is_org_admin; }; userService.isKnownNamespace = function(namespace) { if (namespace == userResponse.username) { return true; } var org = userService.getOrganization(namespace); return !!org; }; userService.getNamespace = function(namespace) { var org = userService.getOrganization(namespace); if (org) { return org; } if (namespace == userResponse.username) { return userResponse; } return null; }; userService.getCLIUsername = function() { if (!userResponse) { return null; } var externalUsername = null; userResponse.logins.forEach(function(login) { if (_EXTERNAL_SERVICES.indexOf(login.service) >= 0) { externalUsername = login.service_identifier; } }); return externalUsername || userResponse.username; }; userService.deleteNamespace = function(info, callback) { var namespace = info.user ? info.user.username : info.organization.name; if (!namespace) { return; } var deleteNamespaceItself = function() { info.progress = 1; info.progressMessage = 'Deleting namespace...'; if (info.user) { ApiService.deleteCurrentUser().then(function(resp) { // Reload the user. userService.load(); callback(true); $location.path('/'); }, errorDisplay); } else { var delParams = { 'name': info.organization.name }; ApiService.deleteOrganization(null, delParams).then(function(resp) { // Reload the user. userService.load(); callback(true); $location.path('/'); }, errorDisplay); } }; var repoIndex = 0; var repositories = null; var deleteAllRepos = function() { if (repoIndex >= repositories.length) { deleteNamespaceItself(); return; } var repoParams = { 'repository': namespace + '/' + repositories[repoIndex]['name'] }; info.progress = repoIndex / repositories.length; info.progressMessage = 'Deleting repository ' + repoParams['repository'] + '...'; ApiService.deleteRepository(null, repoParams).then(function() { repoIndex++; deleteAllRepos(); }, errorDisplay); }; // First delete each repo for the namespace, updating the info so it can show a progress bar. // This is not strictly necessary (as the namespace delete call will do it as well), but it is // a better user experience. var params = { 'namespace': namespace, 'public': false }; var errorDisplay = ApiService.errorDisplay('Could not delete namespace', callback); ApiService.listRepos(null, params).then(function(resp) { repositories = resp['repositories']; deleteAllRepos(); }, errorDisplay); }; userService.currentUser = function() { return userResponse; }; // Update the user in the root scope. userService.updateUserIn($rootScope); // Load the user the first time. userService.load(); return userService; }]);