class UserManager extends Listenable { constructor() { super(); this.users = { }; this.roles = { }; this.loadUsersRequest = new Request(OnTime.REQUEST_URI + "Users", Request.GET, this.loadedUsers.bind(this), this.userLoadingError.bind(this)); this.loadUsersInterval = setInterval(this.loadUsers.bind(this), 60000); this.loadUsers(); this.deleteUserRequest = new Request(OnTime.REQUEST_URI + "User/Delete", Request.POST, this.deletedUser.bind(this), this.userDeletionError.bind(this)); this.createUserRequest = new Request(OnTime.REQUEST_URI + "User/Create", Request.POST, this.createdUser.bind(this), this.userCreationError.bind(this)); this.updateUserRequest = new Request(OnTime.REQUEST_URI + "User", Request.POST, this.updatedUser.bind(this), this.userUpdatingError.bind(this)); this.deleteRoleRequest = new Request(OnTime.REQUEST_URI + "Role/Delete", Request.POST, this.deletedRole.bind(this), this.roleDeletionError.bind(this)); this.createRoleRequest = new Request(OnTime.REQUEST_URI + "Role/Create", Request.POST, this.createdRole.bind(this), this.roleCreationError.bind(this)); this.updateRoleRequest = new Request(OnTime.REQUEST_URI + "Role", Request.POST, this.updatedRole.bind(this), this.roleUpdatingError.bind(this)); } performInitialCalls(eventType, callback) { if (eventType == "roleadded") { for (var roleKey in this.roles) { var addedRole = this.roles[roleKey]; var roleAddedEvent = new Event("roleadded"); roleAddedEvent.role = addedRole; callback(roleAddedEvent); } } else if (eventType == "useradded") { for (var email in this.users) { var addedUser = this.users[email]; var userAddedEvent = new Event("useradded"); userAddedEvent.user = addedUser; callback(userAddedEvent); } } } /** * Shows or hides the elements on the page depending on whether the user has access to them or not. * This is done via CSS classes. */ applyPermissionsToInterface() { //Do nothing if there is no logged in user. if (!this.sessionUser) { return; } var allPermissions = [ "accounts", "user_role", "user_role_grant", "user", "user_samerole", "user_all", "card", "card_category", "project", "report_project", "period", "multiuser", "project_user" ]; var permissions = this.roles[this.sessionUser.role_key].permissions; //Re-enable all elements that were be disabled because of the lack of permission in the last update. if (this.elementsDisabledBecauseOfLackingPermissions) { for (var i = 0; i < this.elementsDisabledBecauseOfLackingPermissions.length; i++) { if (this.elementsDisabledBecauseOfLackingPermissions[i].hasAttribute("disabled")) { this.elementsDisabledBecauseOfLackingPermissions[i].removeAttribute("disabled"); } } } //Disable all elements that this user has no access to. this.elementsDisabledBecauseOfLackingPermissions = [ ]; for (var i = 0; i < allPermissions.length; i++) { var permission = allPermissions[i]; var readElements = document.body.querySelectorAll(".available__" + permission); var writeElements = document.body.querySelectorAll(".available_w__" + permission); if (!permission in permissions) { for (var j = 0; j < readElements.length; j++) { this.elementsDisabledBecauseOfLackingPermissions.push(readElements[j]); } } if ((!permission in permissions) || permissions[permission] == "r") { for (var j = 0; j < writeElements.length; j++) { this.elementsDisabledBecauseOfLackingPermissions.push(writeElements[j]); } } } for (var i = 0; i < this.elementsDisabledBecauseOfLackingPermissions.length; i++) { this.elementsDisabledBecauseOfLackingPermissions[i].setAttribute("disabled", "true"); } for (var permission in permissions) { document.body.classList.add("enable__" + permission); if (permissions[permission] == "w") { document.body.classList.add("enable_w__" + permission); } } } /** * Returns the permissions of the logged in user. */ getPermissions() { if (!this.sessionUser) { return { }; } return this.roles[this.sessionUser.role_key].permissions; } /** * Checks whether the logged in user has the required access ("w" or "r") on the given resource or not and returns this information. * @return true if the resource is available to the user, false if not. */ isResourceAvailable(permission, type) { var permissions = this.getPermissions(); if (permission in permissions && (permissions[permission] == type || (type == "r" && permissions[permission] == "w"))) { return true; } return false; } loadUsers() { if (this.loadUsersRequest.ready) { this.loadUsersRequest.send(); } } loadedUsers(roles) { //Check for deleted and updated roles. for (var roleKey in this.roles) { if (!(roleKey in roles)) { //The role does no longer exist. var roleRemovedEvent = new Event("roleremoved"); roleRemovedEvent.role = this.roles[roleKey]; this.dispatchEvent(roleRemovedEvent); continue; } if (!Object.equals(roles[roleKey], this.roles[roleKey])) { //The role has changed. var roleChangedEvent = new Event("rolechanged"); roleChangedEvent.role = roles[roleKey]; this.dispatchEvent(roleChangedEvent); } } //Process new roles. for (var roleKey in roles) { if (!(roleKey in this.roles)) { var roleAddedEvent = new Event("roleadded"); roleAddedEvent.role = roles[roleKey]; this.dispatchEvent(roleAddedEvent); } } this.roles = roles; //Collect all users and process them as well. var users = { }; for (var roleKey in roles) { for (var email in roles[roleKey].users) { users[email] = roles[roleKey].users[email]; if (users[email].is_session_user) { this.sessionUser = users[email]; //Apply the new permissions if they have changed. if (!Object.equals(this.permissions, this.roles[this.sessionUser.role_key].permissions)) { this.permissions = this.roles[this.sessionUser.role_key].permissions; this.applyPermissionsToInterface(); } } } } //Check for deleted and updated users. for (var email in this.users) { if (!(email in users)) { //The user does no longer exist. var userRemovedEvent = new Event("userremoved"); userRemovedEvent.user = this.users[email]; this.dispatchEvent(userRemovedEvent); continue; } if (!Object.equals(users[email], this.users[email])) { //The user has changed. var userChangedEvent = new Event("userchanged"); userChangedEvent.user = users[email]; this.dispatchEvent(userChangedEvent); } } //Process new users. for (var email in users) { if (!(email in this.users)) { var userAddedEvent = new Event("useradded"); userAddedEvent.user = users[email]; this.dispatchEvent(userAddedEvent); } } this.users = users; } userLoadingError(request, status, error) { alert("Error during the loading of the users:\r\n\r\n" + JSON.stringify(error, true)); } /** * Attempts to delete the given user on the server side. */ deleteUser(user) { this.deleteUserRequest.send(user); } deletedUser(response) { var userRemovedEvent = new Event("userremoved"); userRemovedEvent.user = response; this.dispatchEvent(userRemovedEvent); //Log out if the currently logged in user was deleted. if (response.email == this.sessionUser.email) { this.sessionUser = null; localStorage.removeItem("session"); } delete this.users[response.email]; } userDeletionError(request, status, error) { alert("Error during the deletion of the user:\r\n\r\n" + JSON.stringify(error, true)); } /** * Attempts to create a user with the given data on the server side. */ createUser(user) { this.createUserRequest.send(user); } createdUser(response) { this.users[response.email] = response; this.roles[response.role_key].users[response.email] = response; var userAddedEvent = new Event("useradded"); userAddedEvent.user = response; this.dispatchEvent(userAddedEvent); } userCreationError(request, status, error) { alert("Error during the creation of the user:\r\n\r\n" + JSON.stringify(error, true)); } /** * Attempts to save the given user data on the server. */ updateUser(user) { this.updateUserRequest.send(user); } updatedUser(response) { delete this.users[response.email]; var newEmailAddress = response.new_email; var oldEmailAddress = response.email; delete response.new_email; response.email = newEmailAddress; this.users[newEmailAddress] = response; response.old_email = oldEmailAddress; var userChangedEvent = new Event("userchanged"); userChangedEvent.user = response; this.dispatchEvent(userChangedEvent); } userUpdatingError(request, status, error) { alert("Error while updating the user:\r\n\r\n" + JSON.stringify(error, true)); } /** * Attempts to delete the given role on the server side. */ deleteRole(role) { this.deleteRoleRequest.send(role); } deletedRole(response) { var roleRemovedEvent = new Event("roleremoved"); roleRemovedEvent.role = response; this.dispatchEvent(roleRemovedEvent); delete this.roles[response.role_key]; } roleDeletionError(request, status, error) { alert("Error during the deletion of the role:\r\n\r\n" + JSON.stringify(error, true)); } /** * Attempts to create a role with the given data on the server side. */ createRole(role) { this.createRoleRequest.send(role); } createdRole(response) { this.roles[response.role_key] = response; var roleAddedEvent = new Event("roleadded"); roleAddedEvent.role = response; this.dispatchEvent(roleAddedEvent); } roleCreationError(request, status, error) { alert("Error during the creation of the role:\r\n\r\n" + JSON.stringify(error, true)); } /** * Attempts to save the given role data on the server. */ updateRole(role) { this.updateRoleRequest.send(role); } updatedRole(response) { this.roles[response.role_key] = response; var roleChangedEvent = new Event("rolechanged"); roleChangedEvent.role = response; this.dispatchEvent(roleChangedEvent); } roleUpdatingError(request, status, error) { alert("Error while updating the role:\r\n\r\n" + JSON.stringify(error, true)); } }