Exemplo n.º 1
0
    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()
Exemplo n.º 2
0
 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
Exemplo n.º 3
0
    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()
Exemplo n.º 4
0
 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
Exemplo n.º 5
0
    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()