def post(self): """ Handles building creation, editing and deletion. """ current_user = User.get(self.session['user']['id']) form = self.form try: if form.action == 'delete': if not current_user.super_admin: raise flask.redirect('',code=403) try: id = int(form.id) except ValueError: logger.warning('user %s tries to delete a building with invalid id (id = %s)', current_user.log_name, str(form.id)) raise ImmediateFeedback(form.action, 'invalid_id') try: screens = Screen.selectBy(building=id) if screens.count() > 0: logger.warning('user %s tries to delete a building with screens still present in this building (id = %s)', current_user.log_name, str(id)) raise ImmediateFeedback(form.action, 'delete_building_but_screens_present', [(s.id, s.name) for s in screens]) Building.delete(id) logger.info("building %s has been deleted by user %s", str(id), current_user.log_name) except SQLObjectNotFound as e: logger.warning("user %s tries to delete a building with an id that doesn't exist (id = %s)", current_user.log_name, str(form.id)) raise ImmediateFeedback(form.action, 'no_id_matching') else: name = form.name.strip() if name == "": raise ImmediateFeedback(form.action, 'empty_name') if len(form.name) > Building.sqlmeta.columns['name'].length: raise ImmediateFeedback(form.action, 'too_long_name') if form.action == 'create': try: Building(name=form.name, city=form.city) logger.info("building %s has been created by user %s", form.name, current_user.log_name) except DuplicateEntryError: logger.warning("user %s tries to create a building with a name that already exists (name = %s)", current_user.log_name, form.name) raise ImmediateFeedback(form.action, 'name_already_exists') elif form.action == 'edit': try: id = int(form.id) except ValueError: logger.warning('user %s tries to edit a building with invalid id (id = %s)', current_user.log_name, str(form.id)) raise ImmediateFeedback(form.action, 'invalid_building_id') try: building = Building.get(id) except SQLObjectNotFound as e: logger.warning("user %s tries to edit a building with an id that doesn't exist (id = %s)", current_user.log_name, str(form.id)) raise ImmediateFeedback(form.action, 'no_id_matching') try: building.name = form.name building.city = form.city except DuplicateEntryError: logger.warning("user %s tries to edit the building %s with a name already present (name = %d)", current_user.log_name, str(form.id), form.name) raise ImmediateFeedback(form.action, 'name_already_exists') logger.info("building %s has been edited by user %s (new name = %s)", str(id), current_user.log_name, form.name) add_feedback(form.action, 'ok') except ImmediateFeedback: store_form(form) return self.render_page()
def runTest(self): """ Tests that we can successfully delete a building via the Building page """ new_name = "BuildingNewName" new_city = "BuildingNewCity" post_params = { "action": "edit", "id": str(self.building_id), "name": new_name, "city": new_city } # Do the request r = self.testApp.post('/buildings', params=post_params, status=200) # check that the old name is not there anymore assert Building.selectBy(name=self.building_name).getOne( default=None) is None # check that the building still has the same id but the new name assert Building.get(self.building_id).name == new_name assert Building.get(self.building_id).city == new_city assert r.body is not None
def runTest(self): """ Checks that we cannot delete a building with screens attached to it, and checks that the error is correctly handler for the user """ building_to_test = Building.get(self.building2_id) s = Screen(name="mytestscreen", building=building_to_test, secret="secret") def f(): post_params = {"action": "delete", "id": building_to_test.id} # Use a wrong ID and see if nothing changed and the error has been handled properly for the user r = self.testApp.post('/buildings', params=post_params, status=200) assert r.body is not None check_table_did_not_change(f) s.destroySelf()
def runTest(self): """ Checks that a user cannot add a building with a name composed by only spaces and tabs""" for action in ["create", "edit"]: for name in ["", " ", " ", "\t", " \t "]: post_params = { "action": action, "id": self.building_id, "name": name } # Use a wrong name and see if nothing changed and the error has been handled properly for the user r = self.testApp.post('/buildings', params=post_params, status=200) assert r.body is not None # check that the name did not change assert Building.get( self.building_id).name == self.building_name
def post(self): """ Handles screen creation, editing, deletion, channel subscriptions. """ form = self.form u = User.get(self.session['user']['id']) try: if form.action == 'delete': if not u.super_admin: resp.forbidden() try: screenid = int(form.screenid) except ValueError: raise ImmediateFeedback(form.action, 'invalid_id') try: Screen.delete(screenid) raise ImmediateFeedback(form.action, 'ok') except SQLObjectNotFound as e: raise ImmediateFeedback(form.action, 'no_id_matching') elif form.action == 'subscribe': if form.diff == 'diff': raise ImmediateFeedback(form.action, 'nothing_changed') try: diff = json.loads(form.diff) except (json.JSONDecodeError, ValueError): raise ImmediateFeedback(form.action, 'inconsistent_diff') try: screenid = int(form.screenid) except ValueError: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') for k, v in diff.items(): try: sub = bool(v) except ValueError: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') try: channelid = int(k) except ValueError: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') try: channel = Channel.get(channelid) screen = Screen.get(screenid) if UserPermissions.administrator not in u.highest_permission_level and not ( channel.can_subscribe(u) and u in screen.owners): resp.forbidden() if sub: if hasattr(channel, "plugin" ) and channel.plugin.activated != 'yes': resp.forbidden() screen.subscribe_to(user=u, channel=channel) else: screen.unsubscribe_from(user=u, channel=channel) except SQLObjectNotFound: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') except DuplicateEntryError: # if the user has checked + unchecked the same checkbox, it will appear on the diff, # we just need to do nothing. pass except SQLObjectIntegrityError: # when there id more than one subscription matching the pair channel/screen # TODO: log something pass elif form.action == 'chown': if form.diff == 'diff': raise ImmediateFeedback(form.action, 'nothing_changed') try: diff = json.loads(form.diff) except (json.JSONDecodeError, ValueError): raise ImmediateFeedback(form.action, 'inconsistent_diff') try: screenid = int(form.screenid) except ValueError: raise ImmediateFeedback(form.action, 'screenid') for k, v in diff.items(): try: own = bool(v) except ValueError: raise ImmediateFeedback(form.action, 'invalid_screen/user_id') try: userid = int(k) except ValueError: raise ImmediateFeedback(form.action, 'invalid_screen/user_id') try: screen = Screen.get(screenid) if UserPermissions.administrator not in u.highest_permission_level and u not in screen.owners: resp.forbidden() user = User.get(userid) if own: screen.safe_add_user(user) else: screen.removeUser(user) except SQLObjectNotFound: raise ImmediateFeedback(form.action, 'invalid_screen/user_id') except DuplicateEntryError: # if the user has checked + unchecked the same checkbox, it will appear on the diff, # we just need to do nothing. pass except SQLObjectIntegrityError: # when there is more than one subscription mathing the pair channel/screen # TODO: log something pass elif form.action == 'configure': screen = Screen.get(int(form.id)) screen.shuffle = form.get('shuffle') == 'on' screen.show_postit = form.get('postit') == 'on' screen.show_slide_number = form.get( 'show_slide_number') == 'on' else: building = Building.get(form.building.strip()) name = form.name.strip() form.building_name = None if not building: raise ImmediateFeedback(form.action, 'empty_building') form.building_name = building.name if not name: raise ImmediateFeedback(form.action, 'empty_name') if len(name) > Screen.sqlmeta.columns['name'].length: raise ImmediateFeedback(form.action, 'too_long_name') try: macs = { self.check_mac_address(mac) for mac in form.mac.strip().lower().split(';') if mac } except ValueError: raise ImmediateFeedback(form.action, 'invalid_mac_address') if form.action == 'create': if UserPermissions.administrator not in u.highest_permission_level: resp.forbidden() try: screen = Screen(name=form.name.strip(), building=form.building, location=form.location.strip(), comment=form.comment.strip(), orientation=form.orientation) except DuplicateEntryError: raise ImmediateFeedback(form.action, 'name_already_exists') elif form.action == 'edit': if UserPermissions.administrator not in u.highest_permission_level: resp.forbidden() try: screenid = int(form.screenid) except ValueError: raise ImmediateFeedback(form.action, 'invalid_id') screen = Screen.get(screenid) if screen is None: raise ImmediateFeedback(form.action, 'no_id_matching') try: screen.name = form.name.strip() screen.building = form.building screen.orientation = form.orientation except DuplicateEntryError: raise ImmediateFeedback(form.action, 'name_already_exists') screen.location = form.location.strip() screen.comment = form.comment.strip() else: raise NotImplementedError try: screen_macs = [ screen_mac.mac for screen_mac in screen.macs ] for mac in screen_macs: if mac not in macs: ScreenMac.selectBy(mac=mac).getOne().destroySelf() for mac in macs: if mac not in screen_macs: ScreenMac(screen=screen, mac=mac) except DuplicateEntryError: raise ImmediateFeedback(form.action, 'mac_already_exists') add_feedback(form.action, 'ok') except ImmediateFeedback: pass store_form(form) return self.render_page()