def get_user_info(self, ident, by_name): """ Function to get user info by name or by id (depends on who you are getting it in UI). """ if by_name is True: return User.get_user_info_by_name(ident) else: return User.get_user_info_by_id(ident)
def add_user(self, json, adder_username): """ Processing query for adding new user. All the registration data is provided by JSON body. TODO: Functional tests required! """ # Prepare for permissions check info = User.get_user_info_by_name(adder_username) if not info[0] or not info[1]['username']: # if adder_username does not exists in DB (this is almost impossible) raise SystemError('Wrong adder username provided') adder_info = info[1] if adder_info['group'] not in ['group:admins', 'group:moderators']: raise SystemError("Non-privileged user have access to adding users!" " Something wrong with JSONprocessor security or with DB!") selected_group = json['selected_group'].strip() new_group = json['new_group'].strip() # Pack groups information if new_group: group = new_group elif selected_group: group = selected_group else: return False, 'Wrong groups data' group = 'group:' + group # Check permissions to add such group (IMPORTANT!!!) if group in ['group:admins', 'group:moderators'] and adder_info['group'] != 'group:admins': return False, 'You don\'t have permissions to add new moderator or administrator' # All good. Continue to pack info. username = json['username'].strip() first_name = json['first_name'].strip() last_name = json['last_name'].strip() email = json['email'].strip() send_email = json['send_email'] password = json['new_password'].strip() password_rpt = json['new_password_repeat'].strip() if not password or not password_rpt: return False, "Please repeat new password" if password != password_rpt: return False, 'Passwords does not match' user = User(username, password, email, first_name, last_name, group=group, expire=None) return user.add_to_redis()
def run_machine(self, username, name): """ Asks VM provider to run VM with provided name. """ if not self.__select_vm_provider(): return if not username: return user_machines = User.get_user_machines_by_name(username) if user_machines != [True]: if name not in user_machines: return return self.conn.run_machine(name)
def delete_user(self, id, deleter_username): """ Processing query for deleting user. @param `id` - removing user ID. @param `deleter_username` - username of the person who tries to delete user with provided `id`. This will be used to check deleter's permissions. Please make sure you are using authenticated_userid() to get deleter_username. """ # Determining deleter uid and group info = User.get_user_info_by_name(deleter_username) if not info[0] or not info[1]['username']: # if updater_username does not exists in DB (this is almost impossible) raise SystemError('Wrong deleter username provided') deleter_info = info[1] # Step 2: collecting info about editing user info = User.get_user_info_by_id(id) if not info[0] or not info[1]['username']: # if editing_username does not exists in DB (but this IS possible :) return False, 'Wrong deleting id provided' deleting_user_info = info[1] if deleter_info['username'] == deleting_user_info['username']: return False, "You can't delete yourself" deleter_group = deleter_info['group'] deleted_user_group = deleting_user_info['group'] if deleter_group not in ['group:admins', 'group:moderators']: return False, 'You don\'t have permissions to delete users' if deleted_user_group in ['group:admins', 'group:moderators']: if deleter_group != 'group:admins': return False, 'You don\'t have permissions to delete admins or moderators' return User.remove_user(id)
def destroy_machine(self, username, name): """ Asks VM provider to force stop of VM with provided name. This can be called by UI after calling `stop_machine` function, which can be ignored by VM. """ if not self.__select_vm_provider(): return if not username: return user_machines = User.get_user_machines_by_name(username) if user_machines != [True]: if name not in user_machines: return return self.conn.destroy_machine(name)
def pause_machine(self, username, name): """ Asks VM provider to pause VM with provided name. TODO: This is not implemented yet by any VM provider class, also we don't have unpause function. """ if not self.__select_vm_provider(): return if not username: return user_machines = User.get_user_machines_by_name(username) if user_machines != [True]: if name not in user_machines: return return self.conn.pause_machine(name)
def stop_machine(self, username, name): """ Asks VM provider to stop VM with provided name. This can be ignored by target so UI after calling this method can call `destroy_machine` method to force stopping. """ if not self.__select_vm_provider(): return if not username: return user_machines = User.get_user_machines_by_name(username) if user_machines != [True]: if name not in user_machines: return return self.conn.stop_machine(name)
def vnc_connection(self, username, machine_name, local_user=False): """ Function to prepare proxy VNC connection for VM provider """ global localhost # Step 1: can user view this machine at all? if not username: return False, "Not allowed" user_machines = User.get_user_machines_by_name(username) if user_machines == [True]: pass # Admin elif machine_name not in user_machines: return False, 'Now allowed' # Step 2: Finding your IP to bind to it (this allows remote users to connect) if not local_user: # This was added because local user does not store cookies for WAN IP connection. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.connect(('yandex.ru', 0)) hostname = sock.getsockname()[0] else: hostname = localhost # Step 3: Finding but not binding free port to run sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.bind((hostname, 0)) # Asking OS to bind free port on your WAN IP except Exception: sock.bind(('', 0)) # If failed - on local IP. hostname = localhost finally: listen_port = sock.getsockname()[1] # << Here it is del(sock) # Step 4: Processing by VM manager answer = self.conn.vnc_connection(user_groups=groupfinder(username, None), machine_name=machine_name, listen_port=listen_port, listen_host=hostname, target_host=localhost) # Step 5: Pack answer to client return answer
def get_vms_list(self, username=None, no_cache=False): """ Asking VM provider to provide list of all non-presets VMs, then filtering by allowed. @param no_cache - clear machines list cache flag """ if not self.__select_vm_provider(): return if not username: return vms = self.conn.get_machines_list(no_cache) user_machines = User.get_user_machines_by_name(username) if user_machines == [True]: return vms elif user_machines is not None: vms['offline'] = filter(lambda x: x['name'] in user_machines, vms['offline']) vms['online'] = filter(lambda x: x['name'] in user_machines, vms['online']) return vms else: return None
def update_user(self, json, updater_username): """ TODO: Functional tests required! """ # Step 0: prepare data username = json['username'].strip() first_name = json['first_name'].strip() last_name = json['last_name'].strip() group = json['group'].strip() machines = json['machines'] if not group: return False, 'Bad group name provided' else: group = 'group:' + group email = json['email'].strip() if not email_pattern.match(email): return False, "Wrong email address!" old_password = json['old_password'].strip() password = json['change_password'].strip() password_rpt = json['change_password_confirm'].strip() # # Step 1: getting updater user permissions info = User.get_user_info_by_name(updater_username) if not info[0] or not info[1]['username']: # if updater_username does not exists in DB (this is almost impossible) raise SystemError('Wrong updater username provided') updater_info = info[1] # Step 2: collecting info about editing user info = User.get_user_info_by_name(username) if not info[0] or not info[1]['username']: # if editing_username does not exists in DB (but this IS possible :) return False, 'Wrong changing username provided' changing_user_info = info[1] # Step 3: setting vars change_password = False if any([password, password_rpt]) and not all([password, password_rpt]): return False, "To change password please fill all fields" elif all([password, password_rpt]): if password != password_rpt: return False, "New passwords does not match" elif not 4 <= len(password) <= 16: return False, 'Wrong password length! 4 <= x <= 16' else: change_password = True # Step 4: testing permissions and applying update # There are many cases which must be implemented new_password = None if updater_info['username'] == changing_user_info['username']: # Regular user or superuser changing himself if change_password: if not old_password: return False, "To change password please fill all fields" if not authenticate(updater_info['username'], old_password): return False, "Wrong old password provided" new_password = password group = None # Disabled change of self group User.update_user(username=updater_info['username'], first_name=first_name, last_name=last_name, group=group, email=email, password=new_password) elif updater_info['group'] not in ['group:admins', 'group:moderators']: # Non-privileged user trying to change somebody else return False, "You don't have permissions to change this user" else: # Superuser changing somebody else if changing_user_info['username'] == 'admin': return False, 'Nobody except admin himself can change superadmin profile' if updater_info['group'] == 'group:moderators': if changing_user_info['group'] in ['group:admins', 'group:moderators']: return False, "You don't have permissions to change this user" # IMPORTANT if group in ['group:admins', 'group:moderators']: return False, 'You don\'t have permissions to add new moderator or administrator' if change_password: new_password = password User.update_user(username=changing_user_info['username'], first_name=first_name, last_name=last_name, group=group, email=email, password=new_password, machines=machines) return True, ''
def get_groups_list(self): """ Interface to User model :class: - asking for groups list """ return User.get_all_groups()
def get_users_list(self): """ Interface to User model :class: - asking for users list """ return User.get_all_users()