Пример #1
0
    def post(self):
        """ Handles plugin editing and activation. """
        form = self.form
        try:
            if form.action == 'check_dependencies':
                self.plugin_manager.check_all_plugins_dependencies()
            else:
                plugin_id = int(form.id)
                p = Plugin.get(plugin_id)
                current_user = User.get(self.session['user']['id'])
                if form.action == 'edit':
                    state = 'yes' if 'state' in form and form.state == 'on' else 'no'
                    try:
                        form.name = p.name
                        if p.activated == 'notfound':
                            raise ImmediateFeedback('general', 'plugin_activate_not_found')
                        p.set(activated=state)
                        if p.activated == 'yes':
                            if self.plugin_manager.instantiate_plugin(self.app, p):
                                add_feedback('general', 'plugin_activated')
                            else:
                                raise ImmediateFeedback('general', 'plugin_activation_error')
                        else:
                            add_feedback('general', 'plugin_disabled')
                    except (SQLObjectNotFound, ValueError):
                        raise ImmediateFeedback(form.action, 'invalid_id')
                elif form.action == 'configure':
                    try:
                        for param in p.params_access_rights:
                            param.channel_contributor_read = form.get(param.name + '-cc-r') == 'on'
                            param.channel_contributor_write = form.get(param.name + '-cc-w') == 'on'
                            param.channel_administrator_read = form.get(param.name + '-ca-r') == 'on'
                            param.channel_administrator_write = form.get(param.name + '-ca-w') == 'on'
                            param.administrator_write = form.get(param.name + '-a-r') == 'on'
                            param.administrator_write = form.get(param.name + '-a-w') == 'on'

                        p.cache_activated_default = form.get('cache-activated') == 'on'
                        if 'cache-validity' in form:
                            p.cache_validity_default = int(form['cache-validity'])
                        p.keep_noncomplying_capsules_default = form.get('keep-capsules') == 'on'
                        p.drop_silently_non_complying_slides_default = form.get('drop-silently') == 'on'
                        form.name = p.name
                        add_feedback('general', 'plugin_configured')
                    except (SQLObjectNotFound, ValueError):
                        raise ImmediateFeedback(form.action, 'invalid_id')
                elif form.action == 'delete':
                    if p.channels.count() > 0 and 'confirm-delete' not in form:
                        raise ImmediateFeedback(form.action, 'plugin_has_channels', {'plugin': p.to_dictionary(['id', 'name', 'channels_number', 'screens_number']),
                                                                        'channels': [(c.id, c.name, c.enabled) for c in p.channels]})
                    plugin_name = p.name
                    form.name = plugin_name
                    p.destroySelf()
                    logger.info('The plugin %s has been deleted by %s', plugin_name, current_user.log_name)
                    add_feedback('general', 'plugin_deleted')
        except ImmediateFeedback:
            pass
        store_form(form)
        return self.render_page()
Пример #2
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()
Пример #3
0
 def post(self, channel_id):
     channel = Channel.get(int(channel_id))
     form = self.form
     try:
         if form.action == 'add-channel-to-bundles':
             bundles_diff = json.loads(form.pop('diff', '{}'))
             for bundle_id, part_of in bundles_diff.items():
                 bundle = ChannelBundle.get(int(bundle_id))
                 if part_of:
                     try:
                         bundle.add_channel(channel)
                     except ValueError:
                         raise ImmediateFeedback(form.action,
                                                 'bundle_cycle',
                                                 bundle.name)
                 else:
                     bundle.remove_channel(channel)
             add_feedback(form.action, 'ok')
     except ImmediateFeedback:
         pass
     form.was_bundle = type(
         channel
     ) == ChannelBundle  # Hack to display the bundles tab instead
     form.data_edit = json.dumps([b.id for b in channel.bundles])
     form.channel_id = channel_id
     form.name = channel.name
     store_form(form)
     resp.seeother('/channels')
Пример #4
0
    def common_feedback(self):
        web.ctx.session = self.ictv_app.session
        l = get_feedbacks()
        val = "test"
        assert_false(
            l.has(type="TESTINGFEEDBACK",
                  message="This is a test feedback from the unit test"))
        add_feedback(type="TESTINGFEEDBACK",
                     message="This is a test feedback from the unit test",
                     value=val)
        l = get_next_feedbacks()
        assert_true(
            l.has(type="TESTINGFEEDBACK",
                  message="This is a test feedback from the unit test"))
        assert_is_not_none(
            l.feedback_value(
                type="TESTINGFEEDBACK",
                message="This is a test feedback from the unit test"))
        assert_is_none(
            l.feedback_value(
                type="TESTINGFEEDBACK2",
                message="This is a test feedback from the unit test again"))
        assert_is_not_none(l.feedback_value(type=None, message=None))
        assert_true(l.has_type(type="TESTINGFEEDBACK"))

        i = ImmediateFeedback(
            type="TESTINGFEEDBACK",
            message="This is a test feedback from the unit test",
            value=val)
Пример #5
0
 def post(self, secret):
     user = User.selectBy(reset_secret=secret).getOne(None)
     form = self.form
     try:
         if form.get('password1') != form.get('password2'):
             raise ImmediateFeedback('reset', 'passwords_do_not_match')
         password = form.password1.strip()
         if len(password) <= 3:
             raise ImmediateFeedback('reset', 'password_insufficient')
         user.password = hash_password(form.password1)
         user.reset_secret = utils.generate_secret()  # Make this token one time use
         logger.info('User %s has reset its password from IP %s', user.log_name, flask.g.ip)
     except ImmediateFeedback:
         return self.standalone_renderer.reset(user=user)
     add_feedback('reset', 'ok')
     resp.seeother(flask.url_for("LoginPage"))
Пример #6
0
 def post(self, channel_id, channel):
     """ Handles channel creation, editing, deletion, configuration and user permissions. """
     form = self.form
     current_user = User.get(self.session['user']['id'])
     try:
         if form.action == 'reset-config':
             if form.all == "true":
                 for param_id, param_attrs in channel.plugin.channels_params.items(
                 ):
                     read, write = channel.get_access_rights_for(
                         param_id, current_user)
                     if read and write:
                         channel.plugin_config.pop(param_id, None)
                         # Force SQLObject update
                         channel.plugin_config = channel.plugin_config
             else:
                 param_id = form["reset-param-id"]
                 if param_id not in channel.plugin.channels_params.keys():
                     raise ImmediateFeedback(form.action,
                                             "invalid_param_id")
                 read, write = channel.get_access_rights_for(
                     param_id, current_user)
                 if read and write:
                     channel.plugin_config.pop(param_id, None)
                 else:
                     raise self.forbidden()
                 # Force SQLObject update
                 channel.plugin_config = channel.plugin_config
                 channel.syncUpdate()
             logger.info('params of channel ' + channel.name +
                         ' reset by ' + current_user.log_name)
         elif form.action == 'reset-cache-config':
             if not current_user.super_admin:
                 raise self.forbidden()
             form.name = channel.name
             channel.cache_activated = None
             channel.cache_validity = None
             add_feedback('general', 'channel_cache_reset')
             logger.info(
                 'the cache configuration of channel %s has been reset by user %s',
                 channel.name, current_user.log_name)
         elif form.action == 'reset-filtering-config':
             if not current_user.super_admin:
                 raise self.forbidden()
             form.name = channel.name
             channel.keep_noncomplying_capsules = None
             add_feedback('general', 'channel_filtering_reset')
             logger.info(
                 'the capsule filtering configuration of channel %s has been reset by user %s',
                 channel.name, current_user.log_name)
         add_feedback('general', 'channel_edited')
         add_feedback(form.action, 'ok')
         form.name = channel.name
     except ImmediateFeedback:
         if channel is not None and channel.enabled:
             form.enabled = 'on'
     store_form(form)
     resp.seeother('/channels/config/%d' % channel.id)
Пример #7
0
    def post(self):
        if 'user' in self.session:
            resp.seeother('/')
        form = self.form
        try:
            user = User.selectBy(email=form.email, password=hash_password(form.password)).getOne(None)
            if not user:
                raise ImmediateFeedback('login', 'invalid_credentials')
            self.session['user'] = user.to_dictionary(['id', 'fullname', 'username', 'email'])
        except ImmediateFeedback:
            store_form(form)
            return self.render_page()

        resp.seeother('/')
Пример #8
0
 def post(self, screen_id):
     def wrong_channel(channel, subscribe, user):
         """ returns True if the the user wants to subscribe to the channel while its plugin is not activated or if
             the user tries to subscribe to the channel without being in its authorized subscribers"""
         return subscribe and (type(channel) is PluginChannel and channel.plugin.activated != "yes" or (subscribe and not channel.can_subscribe(user)))
     form = self.form
     try:
         screen = Screen.get(screen_id)
         u = User.get(self.session['user']['id'])
         # Forbid if not admin or does not own this screen
         if not (UserPermissions.administrator in u.highest_permission_level or screen in u.screens):
             logger.warning('user %s tried change subscriptions of screen %d without having the rights to do this',
                            u.log_name, screen.id)
             resp.forbidden()
         diff = json.loads(form.diff)
         if diff == {}:
             logger.info('user %s submitted empty diff for subscriptions of screen %s', u.log_name, screen.name)
             raise ImmediateFeedback("subscription", 'nothing_changed')
         # Do the subscription/unsubscription for every channel in the diff
         subscribed = []
         unsubscribed = []
         try:
             changes = [(Channel.get(channel_id), subscribe) for channel_id, subscribe in diff.items()]
         except SQLObjectNotFound:
             logger.warning('user %s tried to subscribe/unsubscribe screen %d to a channel which does not exist',
                            u.log_name, screen.id)
             resp.forbidden()
         # if somebody tries to subscribe to a channel with a disabled plugin
         wrong_channels = [(channel, subscribe) for channel, subscribe in changes if wrong_channel(channel, subscribe, u)]
         if wrong_channels:
             channel, subscribe = wrong_channels[0]
             if channel.plugin.activated != "yes":
                 logger.warning('user %s tried to %s screen %d to channel %d with disabled plugin',
                                u.log_name, 'subscribe' if subscribe else "unsubscribe", screen.id, channel.id)
                 raise ImmediateFeedback("subscription", "disabled_plugin")
             else:
                 logger.warning('user %s tried to subscribe screen %d to channel %d without having the right to do this',
                                u.log_name, screen.id, channel.id)
                 resp.forbidden()
         for channel, subscribe in changes:
             if subscribe:
                 screen.subscribe_to(u, channel)
                 subscribed.append(str(channel.id))
             else:
                 screen.unsubscribe_from(u, channel)
                 unsubscribed.append(str(channel.id))
         if subscribed and unsubscribed:
             message = "user %s has subscribed screen %d to channel(s) %s and unsubscribed from channel(s) %s" % \
                       (u.log_name, screen.id, ', '.join(subscribed), ', '.join(unsubscribed))
         else:
             message = "user %s has %s screen %d to channel(s) %s" % \
                       (u.log_name, "subscribed" if subscribed else "unsubscribed", screen.id,
                        ', '.join(subscribed if subscribed else unsubscribed))
         logger.info(message)
         add_feedback("subscription", 'ok')
     except SQLObjectNotFound:
         resp.notfound()
     except ImmediateFeedback:
         pass
     store_form(form)
     resp.seeother("/screens/%s/subscriptions" % screen.id)
Пример #9
0
    def post(self, channel_id):
        form = self.form
        u = User.get(self.session['user']['id'])
        subscribed = []
        unsubscribed = []
        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:
            channelid = int(channel_id)
        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:
                screenid = int(k)
            except ValueError:
                raise ImmediateFeedback(form.action,
                                        'invalid_channel/screen_id')
            try:
                channel = Channel.get(channelid)
                if not channel.can_subscribe(u):
                    raise self.forbidden(message="You're not allow to do that")
                screen = Screen.get(screenid)
                if not u in screen.owners:
                    raise self.forbidden(message="You're not allow to do that")
                #sub true -> New subscription
                #sub false -> Remove subscription
                if sub:
                    screen.subscribe_to(u, channel)
                    subscribed.append(str(channel.id))
                else:
                    screen.unsubscribe_from(u, channel)
                    unsubscribed.append(str(channel.id))
                if subscribed and unsubscribed:
                    message = "user %s has subscribed screen %d to channel(s) %s and unsubscribed from channel(s) %s" % \
                              (u.log_name, screen.id, ', '.join(subscribed), ', '.join(unsubscribed))
                else:
                    message = "user %s has %s screen %d to channel(s) %s" % \
                              (u.log_name, "subscribed" if subscribed else "unsubscribed", screen.id,
                               ', '.join(subscribed if subscribed else unsubscribed))
                logger.info(message)
                add_feedback("subscription", 'ok')

            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
                pass
        resp.seeother("/channels/config/%s/subscriptions" % channel_id)
Пример #10
0
    def post(self, bundle_id):
        def wrong_channel(channel, bundle, add):
            """ returns True if the channel to add is the bundle itself
                or if the channel is a PluginChannel with disabled plugin """
            return bundle.id == channel.id or add and type(channel) is PluginChannel and channel.plugin.activated != "yes"
        form = self.form
        try:
            bundle = ChannelBundle.get(bundle_id)
            u = User.get(self.session['user']['id'])
            diff = json.loads(form.diff)
            if diff == {}:
                logger.info('user %s submitted empty diff for bundle management %s', u.log_name, bundle.name)
                raise ImmediateFeedback("manage_channels", 'nothing_changed')
            # Do the subscription/unsubscription for every channel in the diff
            contained = []
            not_contained = []
            try:
                changes = [(Channel.get(channel_id), add) for channel_id, add in diff.items()]
            except SQLObjectNotFound:
                logger.warning('user %s tried to add a channel which does not exist to bundle %d',
                               u.log_name, bundle.id)
                resp.forbidden()
            # if somebody tries to add a channel with a disabled plugin or to add a bundle to itself
            wrong_channels = [(channel, add) for channel, add in changes if wrong_channel(channel, bundle, add)]
            if wrong_channels:
                channel, add = wrong_channels[0]
                if channel.id == bundle.id:
                    logger.warning('user %s tried to %s bundle %d to itself',
                                   u.log_name, 'add' if add else "remove", bundle.id)
                    raise ImmediateFeedback("manage_channels", "added_to_itself")
                else:
                    logger.warning('user %s tried to %s channel %d with disabled plugin to bundle %d',
                                   u.log_name, 'add' if add else "remove", channel.id, bundle.id)
                    raise ImmediateFeedback("manage_channels", "disabled_plugin")
            for channel, add in changes:
                if add:
                    try:
                        bundle.add_channel(channel)
                    except ValueError:
                        logger.warning("user %s has made changes in channels management of bundle %d that created a "
                                       "cycle of bundles by adding channel %d (%s)", u.log_name, bundle.id, channel.id,
                                       channel.name)
                        form.channel_name = channel.name
                        raise ImmediateFeedback("manage_channels", "bundle_cycle")

                    contained.append(str(channel.id))
                else:
                    bundle.remove_channel(channel)
                    not_contained.append(str(channel.id))
            if contained and not_contained:
                message = "user %s has added to channel(s) %s and removed channel(s) %s to bundle %d" % \
                          (u.log_name, ', '.join(contained), ', '.join(not_contained), bundle.id)
            else:
                message = "user %s has %s channel(s) %s to bundle %d" % \
                          (u.log_name, "added" if contained else "removed",
                           ', '.join(contained if contained else not_contained), bundle.id)
            logger.info(message)
            add_feedback("manage_channels", 'ok')
        except SQLObjectNotFound:
            resp.notfound()
        except ImmediateFeedback:
            pass
        store_form(form)
        resp.seeother("/channels/config/%s/manage_bundle" % bundle.id)
Пример #11
0
    def post(self, capsuleid, channel):
        try:
            caps_db = EditorCapsule.get(int(capsuleid))
            slides = caps_db.slides
            form = self.form

            logger_extra = {'channel_name': channel.name, 'channel_id': channel.id}
            logger = get_logger('editor', channel)
            if caps_db.channel != channel:
                return "there is no capsule with the id " + str(capsuleid) + " in the channel " + str(channel.id)
            if form.action == 'delete':
                try:
                    slide = EditorSlide.get(int(form.id))
                except ValueError:
                    return "this is not a valid slide id"
                except SQLObjectNotFound:
                    return "there is no slide with the id " + form.id + " in the channel " + str(channel.id)
                slide.destroySelf()
                slides = EditorSlide.rectify_s_order(capsuleid)
            elif form.action == 'duplicate':
                try:
                    slide = EditorSlide.get(int(form.id))
                except ValueError:
                    return "this is not a valid slide id"
                except SQLObjectNotFound:
                    return "there is no slide with the id " + form.id + " in the channel " + str(channel.id)
                duplicate = slide.duplicate(s_order=-1)
                caps_db.insert_slide_at(duplicate, slide.s_order + 1)
                slides = caps_db.slides
            elif form.action == 'order':
                try:
                    new_order = json.loads(form.order)
                except AttributeError:
                    return "you seem to try to change the order of slides that doesn't exist..."
                except JSONDecodeError:
                    return "invalid changes"
                for k, v in new_order.items():
                    try:
                        slide = EditorSlide.get(int(k))
                        if slide.capsule.id != int(capsuleid):
                            return "you try to change the order of a slide in a different capsule..."
                        slide.s_order = int(v)
                    except ValueError:
                        return "invalid changes"
                    except SQLObjectNotFound:
                        return "You try to change the order of slides that doesn't exist..."
                slides = EditorSlide.rectify_s_order(capsuleid)
            elif form.action == 'theme':
                caps_db = EditorCapsule.get(int(capsuleid))
                if caps_db.channel != channel:
                    return "there is no capsule with the id " + str(capsuleid) + " in the channel " + str(channel.id)

                if form.theme not in Themes:
                    raise ImmediateFeedback(form.action, 'not_existing_theme')
                caps_db.theme = form.theme
            elif form.action == 'edit':
                try:
                    name = form.name.strip()
                    capsule = caps_db
                    if not name:
                        raise ValueError('name')

                    date_from = datetime.datetime.strptime(form['date-from'], "%Y-%m-%dT%H:%M:%S%z")
                    date_to = datetime.datetime.strptime(form['date-to'], "%Y-%m-%dT%H:%M:%S%z")
                    if date_to <= date_from:
                        raise ValueError('dates')

                    capsule.name = name
                    capsule.validity_from = date_from
                    capsule.validity_to = date_to
                except SQLObjectNotFound:
                    return seeother(channel.id, '/')
                except DuplicateEntryError:
                    raise ImmediateFeedback(form.action, 'name_already_exists')
                except ValueError as e:
                    raise ImmediateFeedback(form.action, 'invalid_name' if e.args[0] == 'name' else 'dates_inverted')
            elif form.action.startswith('import'):
                storage_manager = StorageManager(channel.id)
                capsule = caps_db
                background_color = 'white' if 'white-background' in form and form['white-background'] == 'on' else 'black'
                offset = EditorSlide.selectBy(capsule=capsule).max('s_order')
                offset = offset + 1 if offset is not None else 0

                if form.action == 'import-slides' and 'pdf' in form:
                    slide_files = []
                    try:
                        with Color(background_color) as bg:
                            with Image(blob=form.pdf.read(), resolution=150) as pdf:
                                for i, page in enumerate(pdf.sequence):
                                    img_page = Image(image=page)
                                    img_page.background_color = bg
                                    img_page.alpha_channel = False
                                    img_page.format = 'jpeg'
                                    img_page.transform(resize='1920x1080>')
                                    asset = storage_manager.store_file(img_page.make_blob('jpeg'),
                                                                       filename='import-capsule-%d-slide-%d.jpeg' % (capsule.id, offset + i),
                                                                       user=self.session['user']['id'])
                                    slide_files.append(asset)
                        slide_duration = channel.get_config_param('duration') * 1000
                        for i, slide_file in enumerate(slide_files):
                            s = EditorSlide(duration=slide_duration,
                                            content={'background-1': {'file': slide_file.id,
                                                                      'size': 'contain',
                                                                      'color': background_color}},
                                            s_order=offset + i, template='template-image-bg', capsule=capsule)

                            AssetSlideMapping(assetID=slide_file.id, slideID=s.id)
                    except (ValueError, TypeError):
                        logger.warning('An Exception has been encountered when importing PDF file:', extra=logger_extra,
                                       exc_info=True)
                elif form.action == 'import-video' and 'video' in form:
                    try:
                        video_slide = EditorSlide.from_video(form.video, storage_manager, self.transcoding_queue, capsule, self.session['user']['id'], background_color)
                        if type(video_slide) is str:  # Video is being transcoded
                            raise ImmediateFeedback(form.action, 'video_transcoding', video_slide)
                    except TypeError as e:
                        raise ImmediateFeedback(form.action, 'invalid_video_format', e.type)
                else:
                    resp.badrequest()
            elif form.action == 'duration':
                try:
                    slide_id = int(form.id)
                    slide = EditorSlide.get(slide_id)
                    if "duration" in form:
                        duration = float(form.duration)*1000
                        if duration < 0:
                            raise ImmediateFeedback(form.action, "negative_slide_duration")
                    else:
                        duration = -1
                    slide.duration = duration
                except SQLObjectNotFound:
                    return seeother(channel.id, '/')
                except ValueError:
                    raise ImmediateFeedback(form.action, 'invalid_slide_duration')
            add_feedback(form.action, 'ok')
        except ValueError:
            return "this is not a valid capsule id"
        except SQLObjectNotFound:
            return "there is no capsule with the id " + str(capsuleid) + " in the channel " + str(channel.id)
        except ImmediateFeedback:
            store_form(form)
        return self.render_page(channel=channel, capsule=caps_db, slides=caps_db.slides)
Пример #12
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()
Пример #13
0
    def POST(self, channel):
        form = web.input(
            pdf={}, video={}
        )  # Force CGI FieldStorage object to be created for large files
        logger_extra = {'channel_name': channel.name, 'channel_id': channel.id}
        logger = get_logger('editor', channel)
        capsules = None
        try:
            if form['action'] == 'delete':
                try:
                    capsule_id = int(form['id'])
                except ValueError:
                    raise ImmediateFeedback(form.action, 'invalid_id')
                try:
                    capsule = EditorCapsule.get(capsule_id)
                except SQLObjectNotFound:
                    raise ImmediateFeedback(form.action, 'no_id_matching')

                if channel != capsule.channel:
                    raise ImmediateFeedback(form.action, 'wrong_channel')
                if capsule is None:
                    raise ImmediateFeedback(form.action, 'no_id_matching')
                capsule.destroySelf()
                capsules = EditorCapsule.rectify_c_order(channel.id)

            elif form['action'] == 'duplicate':
                try:
                    capsule_id = int(form['id'])
                except ValueError:
                    raise ImmediateFeedback(form.action, 'invalid_id')
                try:
                    capsule = EditorCapsule.get(capsule_id)
                except SQLObjectNotFound:
                    raise ImmediateFeedback(form.action, 'no_id_matching')

                if channel != capsule.channel:
                    raise ImmediateFeedback(form.action, 'wrong_channel')
                if capsule is None:
                    raise ImmediateFeedback(form.action, 'no_id_matching')
                capsule.duplicate(owner_id=self.session['user']['id'])
                capsules = EditorCapsule.rectify_c_order(channel.id)

            elif form.action == 'order':
                try:
                    new_order = json.loads(form.order)
                except AttributeError:
                    return "you seem to try to change the order of slides that doesn't exist..."
                except JSONDecodeError:
                    return "invalid changes"
                capsules_to_reorder = {}
                for k in new_order.keys():
                    try:
                        capsule = EditorCapsule.get(int(k))
                        capsules_to_reorder[k] = capsule
                        if capsule.channel.id != channel.id:
                            return "you try to change the order of a capsule in a different channel..."
                    except SQLObjectNotFound:
                        return "You try to change the order of slides that doesn't exist..."
                sorted_list = sorted(capsules_to_reorder.values(),
                                     key=lambda caps: caps.c_order)
                new_to_old_order = {}
                i = 0
                for elem in sorted_list:
                    new_to_old_order[i] = elem.c_order
                    i += 1
                try:
                    for k, v in new_order.items():
                        capsules_to_reorder[k].c_order = new_to_old_order[int(
                            v)]
                except ValueError:
                    return "invalid changes"
                capsules = EditorCapsule.rectify_c_order(channel.id)

            elif form['action'] == 'create' or form['action'].startswith(
                    'import'):
                name = form['name'].strip()
                if not name:
                    raise ImmediateFeedback(form.action, 'invalid_name')
                try:
                    if 'date-from' in form and 'date-to' in form:
                        try:
                            date_from = datetime.datetime.strptime(
                                form['date-from'], "%Y-%m-%dT%H:%M:%S%z")
                            date_to = datetime.datetime.strptime(
                                form['date-to'], "%Y-%m-%dT%H:%M:%S%z")
                        except ValueError:
                            raise ImmediateFeedback(form.action,
                                                    'wrong_date_values')
                    else:
                        if 'capsule_validity' in channel.plugin_config:
                            validity = int(
                                channel.plugin_config['capsule_validity'])
                        else:
                            validity = int(
                                channel.plugin.
                                channels_params['capsule_validity']['default'])
                        date_from = datetime.datetime.now()
                        time_delta = datetime.timedelta(hours=validity)
                        date_to = date_from + time_delta
                    if date_to <= date_from:
                        raise ImmediateFeedback(form.action, 'dates_inverted')
                    capsule = EditorCapsule(
                        name=form['name'],
                        channel=channel,
                        ownerID=self.session['user']['id'],
                        creation_date=datetime.datetime.now(),
                        c_order=EditorCapsule.select().count(),
                        validity_from=date_from,
                        validity_to=date_to)
                    if form.action.startswith('import'):
                        storage_manager = StorageManager(channel.id)
                        background_color = 'white' if 'white-background' in form and form[
                            'white-background'] == 'on' else 'black'

                        if form.action == 'import-capsule' and 'pdf' in form:

                            slide_files = []
                            try:
                                with Color(background_color) as bg:
                                    with Image(blob=form.pdf.file.read(),
                                               resolution=150) as pdf:
                                        for i, page in enumerate(pdf.sequence):
                                            img_page = Image(image=page)
                                            img_page.background_color = bg
                                            img_page.alpha_channel = False
                                            img_page.format = 'jpeg'
                                            img_page.transform(
                                                resize='1920x1080>')
                                            slide_files.append(
                                                storage_manager.store_file(
                                                    img_page.make_blob('jpeg'),
                                                    filename=
                                                    'import-capsule-%d-slide-%d.jpeg'
                                                    % (capsule.id, i),
                                                    user=self.session['user']
                                                    ['id']))
                                slide_duration = channel.get_config_param(
                                    'duration') * 1000
                                for i, slide_file in enumerate(slide_files):
                                    s = EditorSlide(
                                        duration=slide_duration,
                                        content={
                                            'background-1': {
                                                'file': slide_file.id,
                                                'size': 'contain',
                                                'color': background_color
                                            }
                                        },
                                        s_order=i,
                                        template='template-image-bg',
                                        capsule=capsule)
                                    AssetSlideMapping(assetID=slide_file.id,
                                                      slideID=s.id)
                            except (ValueError, TypeError):
                                logger.warning(
                                    'An Exception has been encountered when importing PDF file:',
                                    extra=logger_extra,
                                    exc_info=True)
                        elif form.action == 'import-video' and 'video' in form:
                            try:
                                video_slide = EditorSlide.from_video(
                                    form.video, storage_manager,
                                    self.transcoding_queue, capsule,
                                    self.session['user']['id'],
                                    background_color)
                                if type(video_slide
                                        ) is str:  # Video is being transcoded
                                    raise ImmediateFeedback(
                                        form.action, 'video_transcoding',
                                        video_slide)
                            except TypeError as e:
                                capsule.destroySelf()
                                raise ImmediateFeedback(
                                    form.action, 'invalid_video_format',
                                    e.type if hasattr(e, 'type') else None)
                        else:
                            raise web.badrequest()

                except DuplicateEntryError:
                    raise ImmediateFeedback(form.action, 'name_already_exists')
            elif form['action'] == 'edit':
                name = form['name'].strip()
                if not name:
                    raise ImmediateFeedback(form.action, 'invalid_name')
                try:
                    capsule_id = int(form['id'])
                except ValueError:
                    raise ImmediateFeedback(form.action, 'invalid_id')
                try:
                    capsule = EditorCapsule.get(capsule_id)
                except SQLObjectNotFound:
                    raise ImmediateFeedback(form.action, 'no_id_matching')

                if channel != capsule.channel:
                    raise ImmediateFeedback(form.action, 'wrong_channel')
                try:
                    capsule.name = name
                except DuplicateEntryError:
                    raise ImmediateFeedback(form.action, 'name_already_exists')
                try:
                    date_from = datetime.datetime.strptime(
                        form['date-from'], "%Y-%m-%dT%H:%M:%S%z")
                    date_to = datetime.datetime.strptime(
                        form['date-to'], "%Y-%m-%dT%H:%M:%S%z")
                except ValueError:
                    raise ImmediateFeedback(form.action, 'wrong_date_values')
                if date_to <= date_from:
                    raise ImmediateFeedback(form.action, 'dates_inverted')
                capsule.validity_from = date_from
                capsule.validity_to = date_to
            add_feedback(form.action, 'ok')
        except ImmediateFeedback:
            pass
        store_form(form)
        return self.render_page(channel, capsules)
Пример #14
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)
Пример #15
0
    def post(self):
        """ Handles user creation, editing and deletion. """
        form = self.form
        super_admin = form.get('super_admin', False) == 'on'
        admin = form.get('admin', False) == 'on'
        if super_admin:
            admin = False
        current_user = User.get(self.session['user']['id'])
        try:
            if form.action == 'create':
                username = form.username.strip()
                fullname = form.fullname.strip()
                form.email = form.email.strip()
                email = None if len(form.email) == 0 or not self.pattern.match(
                    form.email) else form.email

                if email is None and len(form.email) != 0:
                    raise ImmediateFeedback(form.action, 'invalid_email')
                if len(email) > User.sqlmeta.columns['email'].length:
                    raise ImmediateFeedback(form.action, 'too_long_email')
                if len(username) > User.sqlmeta.columns['username'].length:
                    raise ImmediateFeedback(form.action, 'too_long_username')
                if not username:
                    username = None
                elif len(username) < 3:
                    raise ImmediateFeedback(form.action, 'invalid_username')

                try:
                    User(username=username,
                         fullname=fullname,
                         email=email,
                         super_admin=super_admin,
                         disabled=False)
                except DuplicateEntryError:
                    u = User.selectBy(email=form.email).getOne(None)
                    if u is not None:
                        raise ImmediateFeedback(form.action,
                                                'email_already_exists')
                    u = User.selectBy(username=username).getOne(None)
                    if u is not None:
                        raise ImmediateFeedback(form.action,
                                                'username_already_exists')
            elif form.action == 'edit':
                try:
                    form.id = int(form.id)
                    u = User.get(form.id)
                    form.email = form.email.strip()
                    email = None if len(
                        form.email) == 0 or not self.pattern.match(
                            form.email) else form.email
                    form.username = u.username
                    form.fullname = u.fullname

                    if email is None and len(form.email) != 0:
                        raise ImmediateFeedback(form.action, 'invalid_email')

                    if email:
                        try:
                            u.email = email
                        except DuplicateEntryError:
                            raise ImmediateFeedback(form.action,
                                                    'email_already_exists')
                    form.email = u.email
                    if len(email) > User.sqlmeta.columns['email'].length:
                        raise ImmediateFeedback(form.action, 'too_long_email')
                    if not current_user.super_admin:
                        if u.super_admin:
                            resp.forbidden()
                    else:
                        if self.session['user']['id'] != form.id:
                            u.set(super_admin=super_admin, admin=admin)
                except (SQLObjectNotFound, ValueError):
                    raise ImmediateFeedback(form.action, 'invalid_id')
            elif form.action == 'toggle-activation':
                if not current_user.super_admin:
                    resp.forbidden()
                try:
                    form.id = int(form.id)
                    u = User.get(form.id)
                    form.email = u.email
                    u.disabled = not u.disabled
                    add_feedback(
                        form.action,
                        'activated' if not u.disabled else 'deactivated')
                except (SQLObjectNotFound, ValueError):
                    raise ImmediateFeedback(form.action, 'invalid_id')
            add_feedback(form.action, 'ok')
        except ImmediateFeedback:
            pass
        store_form(form)
        resp.seeother('/users')