def serialize_session_block_entry(self, entry, load_children=True): block = entry.session_block data = {} if not load_children: entries = defaultdict(dict) else: entries = {self._get_entry_key(x): self.serialize_timetable_entry(x) for x in entry.children} data.update(self._get_entry_data(entry)) data.update(self._get_color_data(block.session)) data.update(self._get_location_data(block)) data.update({'entryType': 'Session', 'sessionSlotId': block.id, 'sessionId': block.session_id, 'sessionCode': block.session.code, 'title': block.session.title, 'slotTitle': block.title, 'attachments': self._get_attachment_data(block.session), 'code': block.session.code, 'contribDuration': block.session.default_contribution_duration.seconds / 60, 'conveners': [self._get_person_data(x) for x in block.person_links], 'description': block.session.description, 'duration': block.duration.seconds / 60, 'isPoster': block.session.is_poster, 'entries': entries, 'pdf': url_for('sessions.export_session_timetable', block.session), 'url': url_for('sessions.display_session', block.session), 'friendlyId': block.session.friendly_id}) return data
def _process(self): # QRCode (Version 6 with error correction L can contain up to 106 bytes) qr = qrcode.QRCode(version=6, error_correction=qrcode.constants.ERROR_CORRECT_M, box_size=4, border=1) checkin_app = OAuthApplication.find_one( system_app_type=SystemAppType.checkin) qr_data = { "event_id": self.event.id, "title": self.event.title, "date": self.event.start_dt.isoformat(), "version": 1, "server": { "base_url": config.BASE_URL, "consumer_key": checkin_app.client_id, "auth_url": url_for('oauth.oauth_authorize', _external=True), "token_url": url_for('oauth.oauth_token', _external=True) } } json_qr_data = json.dumps(qr_data) qr.add_data(json_qr_data) qr.make(fit=True) qr_img = qr.make_image() output = BytesIO() qr_img.save(output) output.seek(0) return send_file('config.png', output, 'image/png')
def _process_args(self): if not session.user: return self.user = session.user if 'user_id' in request.view_args: self.user = User.get(request.view_args['user_id']) if self.user is None: raise NotFound('This user does not exist') elif request.method == 'GET' and not request.is_xhr and self.flash_user_status: # Show messages about the user's status if it's a simple GET request if self.user.is_deleted: if self.user.merged_into_id is not None: msg = _( 'This user has been merged into <a href="{url}">another user</a>.' ) flash( Markup(msg).format(url=url_for( request.endpoint, self.user.merged_into_user)), 'warning') else: flash(_('This user is marked as deleted.'), 'warning') if self.user.is_pending: flash( _('This user is marked as pending, i.e. it has been attached to something but never ' 'logged in.'), 'warning') if not self.allow_system_user and self.user.is_system: return redirect(url_for('users.user_profile'))
def process_form(self): form = self.manager_form if self.request.state == RequestState.withdrawn: return elif not form.validate_on_submit(): # very unlikely, unless the definition uses a custom form return if 'action_accept' in form and form.action_accept.data: action = 'accept' elif 'action_reject' in form and form.action_reject.data: action = 'reject' elif 'action_save' in form and form.action_save.data: action = 'save' else: # This happens when the request was already processed, e.g. in another # tab or if you simply click the submit button twice. No nee to fail; # just don't do anything. return redirect(url_for('.event_requests_details', self.request)) if action == 'accept': self.definition.accept(self.request, self.manager_form.data, session.user) flash(_('You have accepted this request.'), 'info') elif action == 'reject': self.definition.reject(self.request, self.manager_form.data, session.user) flash(_('You have rejected this request.'), 'info') elif action == 'save': self.definition.manager_save(self.request, self.manager_form.data) flash(_("You have updated the request (only management-specific data)."), 'info') return redirect(url_for('.event_requests_details', self.request))
def serialize_contribution_entry(self, entry): from fossir.modules.events.api import SerializerBase block = entry.parent.session_block if entry.parent else None contribution = entry.contribution data = {} data.update(self._get_entry_data(entry)) if contribution.session: data.update(self._get_color_data(contribution.session)) data.update(self._get_location_data(contribution)) data.update({'entryType': 'Contribution', '_type': 'ContribSchEntry', '_fossil': 'contribSchEntryDisplay', 'contributionId': contribution.id, 'attachments': self._get_attachment_data(contribution), 'description': contribution.description, 'duration': contribution.duration.seconds / 60, 'pdf': url_for('contributions.export_pdf', entry.contribution), 'presenters': map(self._get_person_data, sorted([p for p in contribution.person_links if p.is_speaker], key=lambda x: (x.author_type != AuthorType.primary, x.author_type != AuthorType.secondary, x.display_order_key))), 'sessionCode': block.session.code if block else None, 'sessionId': block.session_id if block else None, 'sessionSlotId': block.id if block else None, 'sessionSlotEntryId': entry.parent.id if entry.parent else None, 'title': contribution.title, 'url': url_for('contributions.display_contribution', contribution), 'friendlyId': contribution.friendly_id, 'references': map(SerializerBase.serialize_reference, contribution.references), 'board_number': contribution.board_number}) return data
def process_form(self): form = self.form if not form.validate_on_submit(): return if not self.request or not self.request.can_be_modified: req = Request(event=self.event, definition=self.definition, created_by_user=session.user) new = True else: req = self.request new = False try: with db.session.no_autoflush: self.definition.send(req, form.data) except RequestModuleError: self.commit = False flash_msg = _('There was a problem sending your request ({0}). Please contact support.') flash(flash_msg.format(self.definition.title), 'error') else: if new: flash_msg = _("Your request ({0}) has been sent.") else: flash_msg = _("Your request ({0}) has been modified.") flash(flash_msg.format(self.definition.title), 'success') if self.is_manager: return redirect(url_for('.event_requests_details', self.event, type=self.definition.name)) else: return redirect(url_for('.event_requests', self.event))
def _sidemenu_items(sender, category, **kwargs): yield SideMenuItem('content', _('Content'), url_for('categories.manage_content', category), 100, icon='eye') yield SideMenuItem('settings', _('Settings'), url_for('categories.manage_settings', category), 90, icon='settings') yield SideMenuItem('protection', _('Protection'), url_for('categories.manage_protection', category), 70, icon='shield')
def _process(self): if self._room.has_live_reservations(): flash(_(u'Cannot delete room with live bookings'), 'error') return redirect(url_for('rooms.roomBooking-roomDetails', self._room)) else: db.session.delete(self._room) flash(_(u'Room deleted'), 'success') return redirect(url_for('rooms_admin.roomBooking-adminLocation', self._room.location))
def process_identity(identity_info): logger.info('Received identity info: %s', identity_info) identity = Identity.query.filter_by( provider=identity_info.provider.name, identifier=identity_info.identifier).first() if identity is None: logger.info('Identity does not exist in the database yet') user = None emails = { email.lower() for email in identity_info.data.getlist('email') if email } if emails: identity_info.data.setlist('email', emails) users = User.query.filter( ~User.is_deleted, User.all_emails.contains(db.func.any(list(emails)))).all() if len(users) == 1: user = users[0] elif len(users) > 1: # TODO: handle this case somehow.. let the user select which user to log in to? raise NotImplementedError( 'Multiple emails matching multiple users') save_identity_info(identity_info, user if user and not user.is_pending else None) if not user or user.is_pending: if user and user.is_pending: logger.info('Found pending user with matching email: %s', user) else: logger.info('Email search did not find an existing user') return redirect( url_for('auth.register', provider=identity_info.provider.name)) else: logger.info('Found user with matching email: %s', user) return redirect( url_for('auth.link_account', provider=identity_info.provider.name)) elif identity.user.is_deleted: raise MultipassException(_('Your fossir profile has been deleted.')) else: user = identity.user if user.is_pending: # This should never happen! raise ValueError('Got identity for pending user') logger.info('Found existing identity %s for user %s', identity, user) # Update the identity with the latest information if identity.multipass_data != identity_info.multipass_data: logger.info('Updated multipass data of identity %s for user %s', identity, user) identity.multipass_data = identity_info.multipass_data if identity.data != identity_info.data: logger.info('Updated data of identity %s for user %s', identity, user) identity.data = identity_info.data if user.is_blocked: raise MultipassException(_('Your fossir profile has been blocked.')) login_user(user, identity)
def _send_confirmation(email, salt, endpoint, template, template_args=None, url_args=None, data=None): template_args = template_args or {} url_args = url_args or {} token = secure_serializer.dumps(data or email, salt=salt) url = url_for(endpoint, token=token, _external=True, **url_args) template_module = get_template_module(template, email=email, url=url, **template_args) send_email(make_email(email, template=template_module)) flash(_('We have sent you a verification email. Please check your mailbox within the next hour and open ' 'the link in that email.')) return redirect(url_for(endpoint, **url_args))
def _extend_admin_menu(sender, **kwargs): if session.user.is_admin: yield SideMenuItem('admins', _("Admins"), url_for('users.admins'), section='user_management') yield SideMenuItem('users', _("Users"), url_for('users.users_admin'), section='user_management')
def _createTabCtrl(self): self._tabCtrl = TabControl() self._tabExistBookings = self._tabCtrl.newTab( 'existing', 'Existing Bookings', url_for('event_mgmt.rooms_booking_list', self.event)) self._tabNewBooking = self._tabCtrl.newTab( 'new', 'New Booking', url_for('event_mgmt.rooms_choose_event', self.event)) if not Reservation.query.with_parent(self.event).has_rows(): self._tabExistBookings.setEnabled(False) self._setActiveTab()
def celery_cmd(args): # remove the celery shell command next(funcs for group, funcs, _ in command_classes if group == 'Main').remove('shell') del CeleryCommand.commands['shell'] if args and args[0] == 'flower': # Somehow flower hangs when executing it using CeleryCommand() so we simply exec it directly. # It doesn't really need the celery config anyway (besides the broker url) try: import flower except ImportError: print cformat('%{red!}Flower is not installed') sys.exit(1) app = OAuthApplication.find_one(system_app_type=SystemAppType.flower) if not app.redirect_uris: print cformat( '%{yellow!}Authentication will fail unless you configure the redirect url for the {} OAuth ' 'application in the administration area.').format(app.name) print cformat( '%{green!}Only fossir admins will have access to flower.') print cformat( '%{yellow}Note that revoking admin privileges will not revoke Flower access.' ) print cformat('%{yellow}To force re-authentication, restart Flower.') auth_args = [ '--auth=^fossir Admin$', '--auth_provider=fossir.core.celery.flower.FlowerAuthHandler' ] auth_env = { 'fossir_FLOWER_CLIENT_ID': app.client_id, 'fossir_FLOWER_CLIENT_SECRET': app.client_secret, 'fossir_FLOWER_AUTHORIZE_URL': url_for('oauth.oauth_authorize', _external=True), 'fossir_FLOWER_TOKEN_URL': url_for('oauth.oauth_token', _external=True), 'fossir_FLOWER_USER_URL': url_for('users.authenticated_user', _external=True) } args = ['celery', '-b', config.CELERY_BROKER] + args + auth_args env = dict(os.environ, **auth_env) os.execvpe('celery', args, env) elif args and args[0] == 'shell': print cformat('%{red!}Please use `fossir shell`.') sys.exit(1) else: CeleryCommand(celery).execute_from_commandline(['fossir celery'] + args)
def _process(self): if not self.plugin.can_manage_vc_rooms(session.user, self.event): flash( _('You are not allowed to create {plugin_name} rooms for this event.' ).format(plugin_name=self.plugin.friendly_name), 'error') return redirect(url_for('.manage_vc_rooms', self.event)) form = self.plugin.create_form(event=self.event) if form.validate_on_submit(): vc_room = VCRoom(created_by_user=session.user) vc_room.type = self.plugin.service_name vc_room.status = VCRoomStatus.created event_vc_room = process_vc_room_association( self.plugin, self.event, vc_room, form) if not event_vc_room: return redirect(url_for('.manage_vc_rooms', self.event)) with db.session.no_autoflush: self.plugin.update_data_vc_room(vc_room, form.data) try: # avoid flushing the incomplete vc room to the database with db.session.no_autoflush: self.plugin.create_room(vc_room, self.event) notify_created(self.plugin, vc_room, event_vc_room, self.event, session.user) except VCRoomError as err: if err.field is None: raise field = getattr(form, err.field) field.errors.append(err.message) db.session.rollback( ) # otherwise the incomplete vc room would be added to the db! else: db.session.add(vc_room) # TODO: notify_created(vc_room, self.event, session.user) flash( _("{plugin_name} room '{room.name}' created").format( plugin_name=self.plugin.friendly_name, room=vc_room), 'success') return jsonify_data(flash=False) form_html = self.plugin.render_form(plugin=self.plugin, event=self.event, form=form, skip_fields=form.skip_fields | {'name'}) return jsonify(html=form_html, js=_pop_injected_js())
def _process_POST(self): self.event.delete('Deleted by user', session.user) flash( _('Event "{}" successfully deleted.').format(self.event.title), 'success') category = self.event.category if category.can_manage(session.user): redirect_url = url_for('categories.manage_content', category) elif category.can_access(session.user): redirect_url = url_for('categories.display', category) else: redirect_url = url_for_index() return jsonify_data(flash=False, redirect=redirect_url)
def _process(self): if not self.plugin.can_manage_vc_rooms(session.user, self.event): flash( _('You are not allowed to remove {} rooms from this event.'). format(self.plugin.friendly_name), 'error') return redirect(url_for('.manage_vc_rooms', self.event)) delete_all = request.args.get('delete_all') == '1' self.event_vc_room.delete(session.user, delete_all=delete_all) flash( _("{plugin_name} room '{room.name}' removed").format( plugin_name=self.plugin.friendly_name, room=self.vc_room), 'success') return redirect(url_for('.manage_vc_rooms', self.event))
def _extend_event_management_menu(sender, event, **kwargs): registration_section = 'organization' if event.type == 'conference' else 'advanced' if not event.can_manage(session.user, 'registration'): return if event.type != 'conference': yield SideMenuItem('participants', _("Participants"), url_for('event_participation.manage', event), section='organization') if event.has_feature('registration'): yield SideMenuItem('registration', _('Registration'), url_for('event_registration.manage_regform_list', event), section=registration_section)
def _extend_event_management_menu(sender, event, **kwargs): if not event.can_manage(session.user): return return SideMenuItem('features', 'Features', url_for('event_features.index', event), section='advanced')
def serialize_session_for_ical(sess): from fossir.modules.events.contributions.util import serialize_contribution_for_ical from fossir.modules.events.util import serialize_person_link return { '_fossil': 'sessionMetadataWithContributions', 'id': sess.id, 'startDate': sess.start_dt, 'endDate': sess.end_dt, 'url': url_for('sessions.display_session', sess, _external=True), 'title': sess.title, 'location': sess.venue_name, 'roomFullname': sess.room_name, 'description': sess.description, 'speakers': [ serialize_person_link(x) for c in sess.contributions for x in c.speakers ], 'contributions': [serialize_contribution_for_ical(c) for c in sess.contributions] }
def _process(self): form = self._make_form() if form.validate_on_submit(): submission = self._save_answers(form) if submission.is_anonymous: submission.user = None submission.submitted_dt = now_utc() submission.is_submitted = True submission.pending_answers = {} db.session.flush() save_submitted_survey_to_session(submission) self.survey.send_submission_notification(submission) flash(_('The survey has been submitted'), 'success') return redirect(url_for('.display_survey_list', self.event)) surveys = Survey.query.with_parent(self.event).filter( Survey.is_visible).all() if not _can_redirect_to_single_survey(surveys): back_button_endpoint = '.display_survey_list' elif self.event.type_ != EventType.conference: back_button_endpoint = 'events.display' else: back_button_endpoint = None return self.view_class.render_template( 'display/survey_questionnaire.html', self.event, form=form, survey=self.survey, back_button_endpoint=back_button_endpoint, partial_completion=self.survey.partial_completion)
def compat_registration(event_id, path=None): url = url_for('event_registration.display_regform_list', confId=event_id) try: registrant_id = int(request.args['registrantId']) authkey = request.args['authkey'] except KeyError: pass else: mapping = (LegacyRegistrationMapping.find( event_id=event_id, legacy_registrant_id=registrant_id, legacy_registrant_key=authkey).first()) if mapping: url = url_for('event_registration.display_regform', mapping.registration.locator.registrant) return redirect(url, 302 if current_app.debug else 301)
def _process(self): defaults = FormDefaults(self.attachment, protected=self.attachment.is_self_protected, skip_attrs={'file'}) if self.attachment.type == AttachmentType.file: form = EditAttachmentFileForm(linked_object=self.object, obj=defaults, file=self.attachment) else: form = EditAttachmentLinkForm(linked_object=self.object, obj=defaults) if form.validate_on_submit(): folder = form.folder.data or AttachmentFolder.get_or_create_default(linked_object=self.object) logger.info('Attachment %s edited by %s', self.attachment, session.user) form.populate_obj(self.attachment, skip={'acl', 'file'}) self.attachment.folder = folder if self.attachment.is_self_protected: # can't use `=` because of https://bitbucket.org/zzzeek/sqlalchemy/issues/3583 self.attachment.acl |= form.acl.data self.attachment.acl &= form.acl.data # files need special handling; links are already updated in `populate_obj` if self.attachment.type == AttachmentType.file: file = form.file.data['added'] if file: self.attachment.file = AttachmentFile(user=session.user, content_type=file.mimetype, filename=secure_filename(file.filename, 'attachment')) self.attachment.file.save(file.stream) signals.attachments.attachment_updated.send(self.attachment, user=session.user) flash(_("The attachment \"{name}\" has been updated").format(name=self.attachment.title), 'success') return jsonify_data(attachment_list=_render_attachment_list(self.object)) template = ('attachments/upload.html' if self.attachment.type == AttachmentType.file else 'attachments/add_link.html') return jsonify_template(template, form=form, existing_attachment=self.attachment, action=url_for('.modify_attachment', self.attachment), protection_message=_render_protection_message(self.object), folders_protection_info=_get_folders_protection_info(self.object))
def _process_args(self): RHSurveyBaseDisplay._process_args(self) self.survey = (Survey.query.filter( Survey.id == request.view_args['survey_id'], Survey.is_visible).options( joinedload('submissions'), joinedload('sections').joinedload('children')).one()) self.submission = (session.user.survey_submissions.filter_by( survey=self.survey, is_submitted=False).first() if session.user else None) if not self.survey.is_active: flash(_('This survey is not active'), 'error') return redirect(url_for('.display_survey_list', self.event)) elif was_survey_submitted(self.survey): flash(_('You have already answered this survey'), 'error') return redirect(url_for('.display_survey_list', self.event))
def _process_conference(self): form = ConferenceLayoutForm(obj=self._get_form_defaults(), event=self.event) css_form = CSSForm() logo_form = LogoForm() tt_theme_settings_form = _make_theme_settings_form(self.event, form.timetable_theme.data) tt_form_valid = tt_theme_settings_form.validate_on_submit() if tt_theme_settings_form else True if form.validate_on_submit() and tt_form_valid: if tt_theme_settings_form: layout_settings.set(self.event, 'timetable_theme_settings', tt_theme_settings_form.data) else: layout_settings.delete(self.event, 'timetable_theme_settings') data = {unicode(key): value for key, value in form.data.iteritems() if key in layout_settings.defaults} layout_settings.set_multi(self.event, data) if form.theme.data == '_custom': layout_settings.set(self.event, 'use_custom_css', True) flash(_('Settings saved'), 'success') return redirect(url_for('.index', self.event)) else: if self.event.logo_metadata: logo_form.logo.data = self.event if self.event.has_stylesheet: css_form.css_file.data = self.event return WPLayoutEdit.render_template('layout_conference.html', self.event, form=form, logo_form=logo_form, css_form=css_form, timetable_theme_settings_form=tt_theme_settings_form)
def _process(self): admins = set( User.query.filter_by(is_admin=True, is_deleted=False).order_by( db.func.lower(User.first_name), db.func.lower(User.last_name))) form = AdminsForm(admins=admins) if form.validate_on_submit(): added = form.admins.data - admins removed = admins - form.admins.data for user in added: user.is_admin = True logger.warn('Admin rights granted to %r by %r [%s]', user, session.user, request.remote_addr) flash( _('Admin added: {name} ({email})').format( name=user.name, email=user.email), 'success') for user in removed: user.is_admin = False logger.warn('Admin rights revoked from %r by %r [%s]', user, session.user, request.remote_addr) flash( _('Admin removed: {name} ({email})').format( name=user.name, email=user.email), 'success') return redirect(url_for('.admins')) return WPUsersAdmin.render_template('admins.html', 'admins', form=form)
def _process(self): token = request.view_args['token'] data = self.token_storage.get(token) valid, existing = self._validate(data) if valid: self.token_storage.delete(token) if existing and existing.is_pending: logger.info("Found pending user %s to be merged into %s", existing, self.user) # If the pending user has missing names, copy them from the active one # to allow it to be marked as not pending and deleted during the merge. existing.first_name = existing.first_name or self.user.first_name existing.last_name = existing.last_name or self.user.last_name merge_users(existing, self.user) flash( _("Merged data from existing '{}' identity").format( existing.email)) existing.is_pending = False self.user.secondary_emails.add(data['email']) signals.users.email_added.send(self.user, email=data['email']) flash( _('The email address {email} has been added to your account.'). format(email=data['email']), 'success') return redirect(url_for('.user_emails'))
def _process(self): extra_preferences = [ pref(self.user) for pref in values_from_signal( signals.users.preferences.send(self.user)) ] form_class = UserPreferencesForm defaults = FormDefaults(**self.user.settings.get_all(self.user)) for pref in extra_preferences: form_class = pref.extend_form(form_class) pref.extend_defaults(defaults) form = form_class(obj=defaults) if form.validate_on_submit(): data = form.data for pref in extra_preferences: pref.process_form_data(data) self.user.settings.set_multi(data) session.lang = self.user.settings.get('lang') session.timezone = (self.user.settings.get('timezone') if self.user.settings.get('force_timezone') else 'LOCAL') flash(_('Preferences saved'), 'success') return redirect(url_for('.user_preferences')) return WPUser.render_template('preferences.html', 'preferences', user=self.user, form=form)
def flash_if_unregistered(event, get_person_links): """Flash message when adding users with no fossir account :param event: Current event :param get_person_links: Callable returning list of person links to check """ old_non_users = {pl for pl in get_person_links() if pl.person.user is None} yield new_non_users = {pl for pl in get_person_links() if pl.person.user is None} added_non_users = len(new_non_users - old_non_users) if not added_non_users: return warning = ngettext('You have added a user with no fossir account.', 'You have added {} users with no fossir account.', added_non_users).format(added_non_users) msg = _( 'An fossir account may be needed to upload materials and/or manage contents.' ) if event.can_manage(session.user): continue_msg = (escape( _('To invite them, please go to the {link_start}Roles page{link_end}' )).format(link_start=Markup('<a href="{}">').format( url_for('persons.person_list', event)), link_end=Markup('</a>'))) else: continue_msg = ngettext( 'Please contact the manager if you think this user should be able to access these ' 'features.', 'Please contact the manager if you think these users should be able to access ' 'these features.', added_non_users) flash(Markup(' ').join([warning, msg, continue_msg]), 'warning')
def _process_form(self, form): name = form.contact_name.data email = form.contact_email.data enabled = form.joined.data uuid = cephalopod_settings.get('uuid') try: if not enabled: unregister_instance() elif enabled and uuid: sync_instance(name, email) elif enabled and not uuid: register_instance(name, email) except HTTPError as err: flash( _("Operation failed, the community hub returned: {err.message}" ).format(err=err), 'error') except Timeout: flash(_("The operation timed-out. Please try again in a while."), 'error') except RequestException as err: flash( _("Unexpected exception while contacting the Community Hub: {err.message}" ).format(err=err)) return redirect(url_for('.index'))
def _extend_event_management_menu(sender, event, **kwargs): if not event.can_manage(session.user): return return SideMenuItem('static', _('Offline Copy'), url_for('static_site.list', event), section='advanced')