예제 #1
0
    def runTest(self):
        """ Tests the ChannelBundle SQLObject """
        fake_plugin = Plugin.byName('fake_plugin')
        fake_plugin.cache_activated_default = False
        pc1 = PluginChannel(name='Channel1',
                            plugin=fake_plugin,
                            subscription_right='public')
        pc2 = PluginChannel(name='Channel2',
                            plugin=fake_plugin,
                            subscription_right='public')
        pc3 = PluginChannel(name='Channel3',
                            plugin=fake_plugin,
                            subscription_right='public')
        channel_bundle = ChannelBundle(name='Channel Bundle',
                                       subscription_right='public')
        channel_bundle2 = ChannelBundle(name='Channel Bundle 2',
                                        subscription_right='public')
        channel_bundle3 = ChannelBundle(name='Channel Bundle 3',
                                        subscription_right='public')

        # Test basic functionality
        channel_bundle.add_channel(pc1)
        channel_bundle.add_channel(pc1)
        channel_bundle.add_channel(pc2)
        channel_bundle.add_channel(pc2)
        channel_bundle.add_channel(pc3)
        channel_bundle.add_channel(pc3)
        assert list(channel_bundle.flatten()) == [pc1, pc2, pc3]

        channel_bundle.remove_channel(pc2)
        assert list(channel_bundle.flatten()) == [pc1, pc3]

        bundle_content = [
            self.ictv_app.plugin_manager.get_plugin_content(pc)
            for pc in channel_bundle.flatten()
        ]
        channels_content = [
            self.ictv_app.plugin_manager.get_plugin_content(pc1),
            self.ictv_app.plugin_manager.get_plugin_content(pc3)
        ]
        for content1, content2 in zip(bundle_content, channels_content):
            capsule1 = content1[0]
            capsule2 = content2[0]
            assert capsule1 == capsule2

        channel_bundle.remove_channel(pc2)
        channel_bundle.remove_channel(pc3)
        channel_bundle.remove_channel(pc1)
        assert list(channel_bundle.flatten()) == []

        assert channel_bundle.get_type_name() == 'Bundle'

        # Test cycle detection
        channel_bundle.add_channel(channel_bundle2)
        channel_bundle2.add_channel(channel_bundle3)
        with pytest.raises(ValueError):
            channel_bundle3.add_channel(channel_bundle)
        with pytest.raises(ValueError):
            channel_bundle.add_channel(channel_bundle)
    def setUp(self, fake_plugin_middleware=lambda: None, ictv_middleware=lambda: None):
        super().setUp(fake_plugin_middleware, ictv_middleware)
        building = Building(name="mytestbuilding")
        self.screen = Screen(name="mytestscreen", building=building, secret="secret")
        self.other_screen = Screen(name="myothertestscreen", building=building, secret="secret")
        self.plugins = [Plugin(name="%s%d" % (self.plugin_name, i), activated="yes") for i in
                        range(self.n_elements - 1)]
        self.plugins.append(Plugin.selectBy(name="fake_plugin").getOne())

        self.plugin_channels = [PluginChannel(name="%s%d" % (self.plugin_channel_name, i), plugin=self.plugins[i],
                                              subscription_right="public") for i in range(self.n_elements)]
        self.bundle_channels = [ChannelBundle(name="%s%d" % (self.bundle_channel_name, i), subscription_right="public")
                                for i in range(self.n_elements)]
        other_channel = PluginChannel(name="other_channel", plugin=self.plugins[0], subscription_right="public")
        User(email=self.user_nothing_email, disabled=False)
        User(email=self.user_administrator_email, disabled=False, admin=True)
        User(email=self.user_super_administrator_email, disabled=False, admin=True, super_admin=True)
        screen_owner = User(email=self.user_screen_owner_email, disabled=False)
        self.screen.safe_add_user(screen_owner)
        other_screen_owner = User(email=self.user_other_screen_owner_email, disabled=False)
        self.other_screen.safe_add_user(other_screen_owner)
        contributor = User(email=self.user_contributor_email, disabled=False)
        [plugin_channel.give_permission_to_user(contributor) for plugin_channel in self.plugin_channels]
        contributor_other_channel = User(email=self.user_contributor_of_other_channel_email, disabled=False)
        other_channel.give_permission_to_user(contributor_other_channel)
        administrator_other_channel = User(email=self.user_administrator_of_other_channel_email, disabled=False)
        other_channel.give_permission_to_user(administrator_other_channel, UserPermissions.channel_administrator)
        channel_admin = User(email=self.user_channel_admin_email, disabled=False)
        [plugin_channel.give_permission_to_user(channel_admin, UserPermissions.channel_administrator) for plugin_channel
         in self.plugin_channels]
예제 #3
0
 def assert_deletion(channel_params=channel_params,
                     bundle_params=bundle_params,
                     status=200):
     assert self.testApp.post('/channels',
                              params=channel_params,
                              status=status).body is not None
     assert PluginChannel.selectBy(id=pc1_id).getOne(None) is None
     assert self.testApp.post('/channels',
                              params=bundle_params,
                              status=status).body is not None
     assert ChannelBundle.selectBy(id=bundle_id).getOne(None) is None
     return (PluginChannel(plugin=self.fake_plugin,
                           name='PC 1',
                           subscription_right='public').id,
             ChannelBundle(name='Bundle',
                           subscription_right='public').id)
예제 #4
0
 def setUp(self):
     super(ChannelsPageTestCase, self).setUp()
     Channel.deleteMany(None)
     self.fake_plugin = Plugin.byName('fake_plugin')
     self.pc1 = PluginChannel(plugin=self.fake_plugin,
                              name='PC 1',
                              subscription_right='public')
     self.pc2 = PluginChannel(plugin=self.fake_plugin,
                              name='PC 2',
                              subscription_right='public')
     self.pc3 = PluginChannel(plugin=self.fake_plugin,
                              name='PC 3',
                              subscription_right='public')
     self.bundle = ChannelBundle(name='Bundle', subscription_right='public')
     self.building = Building(name='Building')
     self.screen = Screen(name='Screen', building=self.building)
     self.user_nothing = User(email='nothing@localhost', disabled=False)
     self.user_contrib = User(email='contrib@localhost', disabled=False)
     self.pc1.give_permission_to_user(self.user_contrib,
                                      UserPermissions.channel_contributor)
     self.user_chan_admin = User(email='chan_admin@localhost',
                                 disabled=False)
     self.user_chan_admin2 = User(email='chan_admin2@localhost',
                                  disabled=False)
     self.pc1.give_permission_to_user(self.user_chan_admin,
                                      UserPermissions.channel_administrator)
     self.pc2.give_permission_to_user(self.user_chan_admin2,
                                      UserPermissions.channel_administrator)
     self.user_screen_admin = User(email='screen_admin@locahost',
                                   disabled=False)
     self.screen.safe_add_user(self.user_screen_admin)
     self.user_admin = User(email='admin@localhost',
                            disabled=False,
                            admin=True)
     self.user_super_admin = User(email='super_admin@localhost',
                                  disabled=False,
                                  admin=True,
                                  super_admin=True)
     self.users = [
         self.user_nothing, self.user_contrib, self.user_chan_admin,
         self.user_chan_admin2, self.user_screen_admin, self.user_admin,
         self.user_super_admin
     ]
예제 #5
0
    def runTest(self):
        fake_plugin = Plugin.byName('fake_plugin')
        user = User(fullname='User', email='test@localhost')

        assert fake_plugin.channels_number == 0
        pc1 = PluginChannel(plugin=fake_plugin,
                            name='Plugin Channel 1',
                            subscription_right='public')
        assert fake_plugin.channels_number == 1
        pc2 = PluginChannel(plugin=fake_plugin,
                            name='Plugin Channel 2',
                            subscription_right='public')
        assert fake_plugin.channels_number == 2
        pc2.destroySelf()
        assert fake_plugin.channels_number == 1

        pc2 = PluginChannel(plugin=fake_plugin,
                            name='Plugin Channel 2',
                            subscription_right='public')
        pc3 = PluginChannel(plugin=fake_plugin,
                            name='Plugin Channel 3',
                            subscription_right='public')
        bundle_channel = ChannelBundle(name='Bundle',
                                       subscription_right='public')
        bundle_channel.add_channel(pc3)
        building = Building(name='building')
        screen1 = Screen(name='Screen1', building=building)
        screen2 = Screen(name='Screen2', building=building)
        screen3 = Screen(name='Screen3', building=building)

        assert fake_plugin.screens_number == 0
        screen1.subscribe_to(user, pc1)
        assert fake_plugin.screens_number == 1
        screen1.subscribe_to(user, pc2)
        assert fake_plugin.screens_number == 1
        screen2.subscribe_to(user, pc3)
        assert fake_plugin.screens_number == 2
        screen2.subscribe_to(user, bundle_channel)
        assert fake_plugin.screens_number == 2
        screen3.subscribe_to(user, bundle_channel)
        assert fake_plugin.screens_number == 3
예제 #6
0
 def preview_channel(self):
     c = ChannelBundle(name='A', subscription_right='public')
     r = self.testApp.get('/preview/channels/1/' + c.secret)
     assert_equal(r.status, 200)
예제 #7
0
    def runTest(self):
        """ Tests the Channel SQLObject """
        Channel.deleteMany(None)
        fake_plugin = Plugin(name='fake_plugin', activated='notfound')
        channel = Channel(name='Channel',
                          subscription_right='public',
                          secret='abcdef')
        plugin_channel = PluginChannel(name='Channel2',
                                       plugin=fake_plugin,
                                       subscription_right='public')
        bundle_channel = ChannelBundle(name='Channel3',
                                       subscription_right='public')
        building = Building(name='building')
        screen = Screen(name='Screen', building=building)
        user = User(fullname='User', email='test@localhost')
        user2 = User(fullname='User2', email='test2@localhost')

        # Test can_subscribe()
        def test_channel_subscription(c, u):
            def assert_subscription_no_perm():
                assert c.can_subscribe(u)
                c.subscription_right = 'restricted'
                assert not c.can_subscribe(u)
                c.subscription_right = 'private'
                assert not c.can_subscribe(u)
                c.subscription_right = 'public'
                assert c.can_subscribe(u)

            def assert_subscription_admin():
                assert c.can_subscribe(u)
                c.subscription_right = 'restricted'
                assert c.can_subscribe(u)
                c.subscription_right = 'private'
                assert c.can_subscribe(u)
                c.subscription_right = 'public'
                assert c.can_subscribe(u)

            def assert_subscription_super_admin():
                assert c.can_subscribe(u)
                c.subscription_right = 'restricted'
                assert c.can_subscribe(u)
                c.subscription_right = 'private'
                assert c.can_subscribe(u)
                c.subscription_right = 'public'
                assert c.can_subscribe(u)

            assert_subscription_no_perm()
            user.admin = True
            assert_subscription_admin()
            user.admin = False
            user.super_admin = True
            assert_subscription_super_admin()
            user.super_admin = False

        test_channel_subscription(channel, user)
        test_channel_subscription(plugin_channel, user)
        test_channel_subscription(bundle_channel, user)

        # Test get_channels_authorized_subscribers_as_json()
        def test_channel_subscribers(c):
            def assert_no_users():
                assert Channel.get_channels_authorized_subscribers_as_json(
                    [c]) == '{"%d": []}' % c.id

            def assert_only_user(u):
                assert Channel.get_channels_authorized_subscribers_as_json(
                    [c]) == '{"%d": [%d]}' % (c.id, u.id)

            def assert_users(*users):
                for u in json.loads(
                        Channel.get_channels_authorized_subscribers_as_json(
                            [c]))[str(c.id)]:
                    assert u in [u.id for u in users]

            assert_no_users()
            c.safe_add_user(user)
            assert_only_user(user)
            # check that there is no duplicate
            c.safe_add_user(user)
            assert_only_user(user)
            c.removeUser(user)
            c.safe_add_user(user)
            assert_only_user(user)
            c.safe_add_user(user2)
            assert_users(user, user2)
            c.removeUser(user)
            assert_only_user(user2)
            c.removeUser(user2)
            assert_no_users()

        test_channel_subscribers(channel)
        test_channel_subscribers(plugin_channel)
        test_channel_subscribers(bundle_channel)

        # Test get_visible_channels_of()
        def test_visible_channels(u):
            def assert_no_channels():
                assert Channel.get_visible_channels_of(u) == set()

            def assert_channel(c):
                assert Channel.get_visible_channels_of(u) == {c}

            def assert_all_channels():
                assert Channel.get_visible_channels_of(u) == {
                    channel, plugin_channel, bundle_channel
                }

            def assert_public_channels():
                channel.subscription_right = 'restricted'
                assert Channel.get_visible_channels_of(u) == {
                    plugin_channel, bundle_channel
                }
                channel.subscription_right = 'private'
                assert Channel.get_visible_channels_of(u) == {
                    plugin_channel, bundle_channel
                }
                channel.subscription_right = 'public'

            assert_no_channels()
            u.admin = True
            assert_all_channels()
            u.admin = False
            assert_no_channels()
            u.super_admin = True
            assert_all_channels()
            u.super_admin = False
            assert_no_channels()

            screen.addUser(u)
            assert_public_channels()
            screen.removeUser(u)
            assert_no_channels()

            channel.subscription_right = 'restricted'
            assert_no_channels()
            channel.addUser(u)
            assert_channel(channel)
            screen.addUser(u)
            assert_all_channels()
            channel.removeUser(u)
            screen.removeUser(u)
            assert_no_channels()
            channel.subscription_right = 'public'

            plugin_channel.give_permission_to_user(
                u, UserPermissions.channel_contributor)
            assert_channel(plugin_channel)
            plugin_channel.give_permission_to_user(
                u, UserPermissions.channel_administrator)
            assert_channel(plugin_channel)
            plugin_channel.remove_permission_to_user(u)
            assert_no_channels()

        test_visible_channels(user)
        test_visible_channels(user2)

        # Test get_screens_channels_from()
        def test_screens_channels(u):
            def assert_no_channels():
                assert set(Channel.get_screens_channels_from(u)) == set()

            def assert_channel(c):
                assert set(Channel.get_screens_channels_from(u)) == {c}

            def assert_channels(*channels):
                assert set(
                    Channel.get_screens_channels_from(u)) == set(channels)

            def assert_all_channels():
                assert set(Channel.get_screens_channels_from(u)) == {
                    channel, plugin_channel, bundle_channel
                }

            assert_all_channels()
            channel.subscription_right = 'restricted'
            plugin_channel.subscription_right = 'restricted'
            bundle_channel.subscription_right = 'restricted'
            assert_no_channels()
            u.super_admin = True
            assert_all_channels()
            u.super_admin = False
            assert_no_channels()
            channel.addUser(u)
            assert_channel(channel)
            channel.removeUser(u)
            assert_no_channels()
            screen.addUser(user)
            screen.subscribe_to(user, channel)
            assert_channel(channel)
            screen.subscribe_to(user, bundle_channel)
            assert_channels(channel, bundle_channel)

            channel.subscription_right = 'public'
            plugin_channel.subscription_right = 'public'
            bundle_channel.subscription_right = 'public'

        test_screens_channels(user)

        # Test get_preview_link()
        assert channel.get_preview_link(
        ) == '/preview/channels/%d/abcdef' % channel.id
예제 #8
0
    def runTest(self):
        """ Tests the Screen SQLObject """
        Channel.deleteMany(None)
        Screen.deleteMany(None)
        channel = Channel(name='Channel',
                          subscription_right='public',
                          secret='abcdef')
        plugin_channel = PluginChannel(name='Channel2',
                                       plugin=Plugin.byName('fake_plugin'),
                                       subscription_right='public')
        plugin_channel2 = PluginChannel(name='Channel3',
                                        plugin=Plugin.byName('fake_plugin'),
                                        subscription_right='public')
        bundle_channel = ChannelBundle(name='Channel4',
                                       subscription_right='public')
        bundle_channel.add_channel(plugin_channel2)
        building = Building(name='building')
        screen = Screen(name='Screen', building=building, secret='abcdef')
        screen2 = Screen(name='Screen2', building=building)
        user = User(fullname='User', email='test@localhost')
        user2 = User(fullname='User2', email='test2@localhost')

        # Miscellaneous test
        assert screen.get_view_link() == '/screens/%d/view/abcdef' % screen.id
        assert screen.get_client_link(
        ) == '/screens/%d/client/abcdef' % screen.id
        assert screen.get_macs_string() == ''
        assert screen not in user.screens
        screen.safe_add_user(user)
        assert screen in user.screens
        assert screen not in user2.screens
        screen.removeUser(user)
        assert screen not in user2.screens

        # Test subscription
        assert not screen.is_subscribed_to(channel)
        screen.subscribe_to(user, channel)
        assert screen.is_subscribed_to(channel)
        sub = screen.subscriptions[0]
        screen.subscribe_to(user2, channel, weight=42)
        assert sub.created_by == user2
        assert sub.weight == 42
        assert screen.is_subscribed_to(channel)
        assert list(screen.subscribed_channels) == [channel]
        screen.unsubscribe_from(user2, channel)
        assert not screen.is_subscribed_to(channel)

        # Test macs
        ScreenMac(screen=screen, mac='00b16b00b500')
        ScreenMac(screen=screen, mac='00b16b00b501')
        assert screen.get_macs_string(
        ) == '00:b1:6b:00:b5:00;00:b1:6b:00:b5:01'

        # Test get_visible_screens_of()
        assert list(Screen.get_visible_screens_of(user)) == list(
            Screen.get_visible_screens_of(user2)) == []
        user.admin = True
        assert list(Screen.get_visible_screens_of(user)) == [screen, screen2]
        assert list(Screen.get_visible_screens_of(user2)) == []
        user.admin = False
        user2.super_admin = True
        assert list(Screen.get_visible_screens_of(user2)) == [screen, screen2]
        assert list(Screen.get_visible_screens_of(user)) == []
        user2.super_admin = False
        screen.safe_add_user(user)
        screen2.safe_add_user(user2)
        assert list(Screen.get_visible_screens_of(user)) == [screen]
        assert list(Screen.get_visible_screens_of(user2)) == [screen2]

        # Test channel content
        screen.subscribe_to(user, plugin_channel)
        screen.subscribe_to(user, bundle_channel)
        screen_content = screen.get_channels_content(self.ictv_app)
        assert len(screen_content) == 2
        assert len(screen_content[0].get_slides()) == 1
        assert screen_content[0].get_slides()[0].get_content() == {
            'background-1': {
                'size': 'contain',
                'src': ''
            },
            'title-1': {
                'text': 'Channel2'
            },
            'text-1': {
                'text': ''
            }
        }
        assert len(screen_content[1].get_slides()) == 1
        assert screen_content[1].get_slides()[0].get_content() == {
            'background-1': {
                'size': 'contain',
                'src': ''
            },
            'title-1': {
                'text': 'Channel3'
            },
            'text-1': {
                'text': ''
            }
        }
        screen.shuffle = True
        assert len(screen.get_channels_content(self.ictv_app)) == 2
예제 #9
0
    def POST(self):
        """ Handles channel creation, editing, deletion, configuration and user permissions. """
        form = web.input()
        current_user = User.get(self.session['user']['id'])
        channel = None
        try:
            if form.action.startswith('create') or form.action.startswith(
                    'edit'):
                # Prepare creation or edition of channels/bundles
                name = form.name.strip()
                description = form.description if form.description and form.description.strip(
                ) else None
                enabled = form.get('enabled') == 'on'
                if form.subscription_right not in [
                        'public', 'restricted', 'private'
                ]:
                    raise ImmediateFeedback(form.action,
                                            'invalid_subscription_right')
                if len(name) < 3:
                    raise ImmediateFeedback(form.action, 'invalid_name')

            if form.action.startswith('create'):
                if UserPermissions.administrator not in current_user.highest_permission_level:
                    logger.warning(
                        'user %s tried to create a channel without being admin',
                        current_user.log_name)
                    raise web.forbidden()

                try:
                    if form.action == 'create-channel':
                        try:
                            plugin_id = int(form.plugin)
                        except ValueError:
                            raise ImmediateFeedback(form.action,
                                                    'invalid_plugin')
                        p = Plugin.get(plugin_id)
                        channel = PluginChannel(
                            name=name,
                            plugin=p,
                            subscription_right=form.subscription_right,
                            description=description,
                            enabled=enabled)
                        if p.webapp:
                            self.plugin_manager.add_mapping(self.app, channel)

                    elif form.action == 'create-bundle':
                        channel = ChannelBundle(
                            name=name,
                            description=description,
                            subscription_right=form.subscription_right,
                            enabled=enabled)
                    else:
                        raise web.badrequest()
                except SQLObjectNotFound:
                    raise ImmediateFeedback(form.action, 'invalid_plugin')
                except DuplicateEntryError:
                    raise ImmediateFeedback(form.action, 'name_already_exists')
                logger.info('channel ' + channel.name + ' created by ' +
                            current_user.log_name)
            elif form.action.startswith('edit'):
                if UserPermissions.administrator not in current_user.highest_permission_level:
                    raise web.forbidden()
                try:
                    form.id = int(form.id)
                    channel = (PluginChannel if form.action == 'edit-channel'
                               else Channel).get(form.id)
                except (SQLObjectNotFound, ValueError):
                    raise ImmediateFeedback(form.action, 'invalid_id')

                previous_state = {
                    'name': channel.name,
                    'description': channel.description,
                    'subscription_right': channel.subscription_right,
                    'enabled': channel.enabled
                }
                new_state = {
                    'name': name,
                    'description': description,
                    'subscription_right': form.subscription_right,
                    'enabled': enabled
                }
                state_diff = dict(
                    set(new_state.items()) - set(previous_state.items()))

                if form.action == 'edit-channel':
                    try:
                        plugin_id = int(form.plugin)
                        p = Plugin.get(plugin_id)
                        add_mapping = p.webapp and channel.plugin != p
                        previous_state['plugin'] = channel.plugin
                        new_state['plugin'] = p
                    except (SQLObjectNotFound, ValueError):
                        raise ImmediateFeedback(form.action, 'invalid_plugin')
                elif form.action == 'edit-bundle':
                    pass  # There is nothing more to edit for a bundle than a channel
                else:
                    raise web.badrequest()

                try:
                    channel.set(**new_state)
                except DuplicateEntryError:
                    channel.set(**previous_state)  # Rollback
                    raise ImmediateFeedback(form.action, 'name_already_exists')

                logger.info(
                    '[Channel %s (%d)] ' % (channel.name, channel.id) +
                    current_user.log_name + ' edited the channel.\n'
                    'Previous state: %s\n' % str({
                        k: v
                        for k, v in previous_state.items() if k in state_diff
                    }) + 'New state: %s' % str(state_diff))

                if form.action == 'edit-channel' and add_mapping:
                    self.plugin_manager.add_mapping(self.app, channel)
            elif form.action.startswith('delete'):
                if not current_user.super_admin:
                    logger.warning(
                        'the user %s tried to delete a channel without having the rights to do it',
                        current_user.log_name)
                    raise web.forbidden()
                try:
                    form.id = int(form.id)
                    channel = Channel.get(form.id)
                    if channel.subscriptions.count(
                    ) > 0 and 'confirm-delete' not in form:
                        raise ImmediateFeedback(
                            form.action, 'channel_has_subscriptions', {
                                'channel': {
                                    'name':
                                    channel.name,
                                    'id':
                                    channel.id,
                                    'description':
                                    channel.description,
                                    'subscription_right':
                                    channel.subscription_right
                                },
                                'plugin_id':
                                channel.plugin.id
                                if form.action == 'delete-channel' else None,
                                'subscriptions':
                                [(s.screen.id, s.screen.name,
                                  s.screen.building.name)
                                 for s in channel.subscriptions]
                            })
                    form.name = channel.name
                    channel_name = channel.name
                    channel.destroySelf()
                    logger.info('the channel %s has been deleted by user %s',
                                channel_name, current_user.log_name)
                except (SQLObjectNotFound, ValueError) as e:
                    print(e)
                    raise ImmediateFeedback(form.action, 'invalid_id')
            elif form.action == 'add-users-channel':
                try:
                    if 'users' not in form:
                        raise web.badrequest()
                    form.users = json.loads(form.users)
                    form.id = int(form.id)
                    channel = PluginChannel.get(form.id)
                    if not channel.has_admin(
                            current_user
                    ) and UserPermissions.administrator not in current_user.highest_permission_level:
                        raise web.forbidden()
                    form.name = channel.name
                    for user_id, diff in form.users.items():
                        user_id = int(user_id)
                        user = User.get(user_id)
                        if 'permission' in diff:
                            permission_level = diff['permission']
                            new_permission_level = UserPermissions(
                                permission_level)
                            old_permission_level = channel.get_channel_permissions_of(
                                user)
                            if new_permission_level == UserPermissions.no_permission \
                                    and (UserPermissions.administrator in current_user.highest_permission_level or old_permission_level == UserPermissions.channel_contributor):
                                channel.remove_permission_to_user(user)
                                logger.info(
                                    'permissions of user %s concerning channel %s have been removed by user %s',
                                    user.log_name, channel.name,
                                    current_user.log_name)
                            elif (new_permission_level == UserPermissions.channel_contributor and channel.has_admin(
                                    current_user) and old_permission_level == UserPermissions.no_permission) \
                                    or (new_permission_level in UserPermissions.channel_administrator and UserPermissions.administrator in current_user.highest_permission_level):
                                channel.give_permission_to_user(
                                    user, new_permission_level)
                                logger.info(
                                    'permissions of user %s concerning channel %s have been set to %s by user %s',
                                    user.log_name, channel.name,
                                    UserPermissions.get_permission_string(
                                        new_permission_level),
                                    current_user.log_name)
                        if 'authorized_subscriber' in diff:
                            authorized_subscriber = diff[
                                'authorized_subscriber']
                            if authorized_subscriber and (
                                    user
                                    not in channel.authorized_subscribers):
                                channel.addUser(user)
                                logger.info(
                                    'the user %s has been added to channel %s as authorized subscriber by user %s',
                                    user.log_name, channel.name,
                                    current_user.log_name)
                            elif not authorized_subscriber and (
                                    user in channel.authorized_subscribers):
                                channel.removeUser(user)
                                logger.info(
                                    'the user %s has been removed from channel %s as authorized subscriber by user %s',
                                    user.log_name, channel.name,
                                    current_user.log_name)
                except (SQLObjectNotFound, ValueError):
                    raise ImmediateFeedback(form.action, 'invalid_id')
                except (KeyError, json.JSONDecodeError):
                    raise ImmediateFeedback(form.action, 'invalid_users')
            elif form.action == 'configure':
                try:
                    form.id = int(form.id)
                    channel = PluginChannel.get(form.id)
                    pattern = re.compile(r'list\[.*\]')
                    if UserPermissions.administrator in current_user.highest_permission_level or UserPermissions.channel_administrator in channel.get_channel_permissions_of(
                            current_user) or channel.has_contrib(current_user):
                        for k, v in [(k, v) for k, v in
                                     channel.plugin.channels_params.items()
                                     if channel.get_access_rights_for(
                                         k, current_user)[1]]:
                            # Iterates on the parameters the current user can write to
                            if v['type'] == 'bool':
                                value = k in form and form[k] == 'on'
                            elif v['type'] == 'int':
                                value = int(form[k])
                                if not (v.get('min', float('-inf')) <= value <=
                                        v.get('max', float('inf'))):
                                    continue
                            elif pattern.match(v['type']):
                                inner_type = v['type'][5:-1]
                                if inner_type == 'string':
                                    value = web.input(**{k: ['']})[k]
                                elif pattern.match(inner_type):
                                    inner_type = inner_type[5:-1]
                                    if inner_type == 'string':
                                        delimiter = form[k + '-delimiter']
                                        values = web.input(**{k: ['']})[k]
                                        lists = []
                                        l = []
                                        for v in values:
                                            if v == delimiter:
                                                lists.append(l)
                                                l = []
                                            else:
                                                l.append(v)
                                        value = lists

                            elif k in form:
                                if v['type'] == 'template' and form[k] == '~':
                                    value = None
                                else:
                                    value = form[k]
                            else:
                                continue

                            if channel.get_config_param(k) != value:
                                channel.plugin_config[k] = value
                                logger.info(
                                    'the %s parameter of channel %s has been changed to %s by user %s',
                                    k, channel.name, value,
                                    current_user.log_name)

                        if current_user.super_admin:
                            channel.cache_activated = 'cache-activated' in form and form[
                                'cache-activated'] == 'on'
                            channel.cache_validity = int(
                                form['cache-validity']
                            ) if 'cache-validity' in form and form[
                                'cache-validity'] else channel.cache_validity
                            channel.keep_noncomplying_capsules = 'keep-capsules' in form and form[
                                'keep-capsules'] == 'on'

                        channel.plugin_config = channel.plugin_config  # Force SQLObject update
                        try:
                            self.plugin_manager.invalidate_cache(
                                channel.plugin.name, channel.id)
                            self.plugin_manager.get_plugin(
                                channel.plugin.name).get_content(channel.id)
                        except MisconfiguredParameters as e:
                            for faulty_param in e:
                                add_feedback(form.action, faulty_param[0],
                                             faulty_param)
                            raise web.seeother('/channels/%d' % channel.id)
                        except Exception as e:
                            add_feedback(form.action, 'general_error', str(e))
                            raise web.seeother('/channels/%d' % channel.id)
                    else:
                        raise web.forbidden()
                    form.name = channel.name
                except (SQLObjectNotFound, ValueError):
                    raise ImmediateFeedback(form.action, 'invalid_id')
            if channel:
                form.name = channel.name
            add_feedback(form.action, 'ok')

        except ImmediateFeedback:
            if channel is not None and channel.enabled:
                form.enabled = 'on'
        store_form(form)
        return self.render_page(current_user)