def reset_confirm(code: str) -> str: # pragma: no cover user = UserMapper.get_by_reset_code(code) if not user: logger.log('info', 'auth', 'unknown reset code') flash(_('invalid password reset confirmation code'), 'error') abort(404) hours = session['settings']['reset_confirm_hours'] if datetime.datetime.now() > user.password_reset_date + datetime.timedelta( hours=hours): logger.log('info', 'auth', 'reset code expired') flash(_('This reset confirmation code has expired.'), 'error') abort(404) password = UserMapper.generate_password() user.password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') user.password_reset_code = None user.password_reset_date = None user.login_failed_count = 0 user.update() subject = _('New password for %(sitename)s', sitename=session['settings']['site_name']) body = _('New password for %(username)s', username=user.username) + ' ' body += _('at') + ' ' + request.scheme + '://' + request.headers[ 'Host'] + ':\n\n' body += uc_first(_('username')) + ': ' + user.username + '\n' body += uc_first(_('password')) + ': ' + password + '\n' if send_mail(subject, body, user.email, False): flash(_('Send new password mail to %(email)s.', email=user.email), 'info') else: flash( _('Failed to send password mail to %(email)s.', email=user.email), 'error') return redirect(url_for('login'))
def user_insert(): form = UserForm() form.group.choices = get_groups() if not session['settings']['mail']: del form.send_info if form.validate_on_submit(): user_id = UserMapper.insert(form) flash(_('user created'), 'info') if session['settings']['mail'] and form.send_info.data: # pragma: no cover subject = _( 'Your account information for %(sitename)s', sitename=session['settings']['site_name']) body = _('Account information for %(username)s', username=form.username.data) + ' ' body += _('at') + ' ' + request.scheme + '://' + request.headers['Host'] + '\n\n' body += uc_first(_('username')) + ': ' + form.username.data + '\n' body += uc_first(_('password')) + ': ' + form.password.data + '\n' if send_mail(subject, body, form.email.data, False): flash( _('Sent account information mail to %(email)s.', email=form.email.data), 'info') else: flash( _('Failed to send account details to %(email)s.', email=form.email.data), 'error') return redirect(url_for('user_index')) if form.continue_.data == 'yes': return redirect(url_for('user_insert')) return redirect(url_for('user_view', id_=user_id)) return render_template('user/insert.html', form=form)
def user_insert() -> Union[str, Response]: form = UserForm() form.group.choices = get_groups() if not session['settings']['mail']: del form.send_info if form.validate_on_submit(): user_id = User.insert(form) flash(_('user created'), 'info') if session['settings']['mail'] \ and form.send_info.data: # pragma: no cover subject = _('Your account information for %(sitename)s', sitename=session['settings']['site_name']) body = _('Account information for %(username)s', username=form.username.data) + \ f" {_('at')} {request.scheme}://{request.headers['Host']}\n\n" \ f"{uc_first(_('username'))}: {form.username.data}\n" \ f"{uc_first(_('password'))}: {form.password.data}\n" if send_mail(subject, body, form.email.data, False): flash( _('Sent account information mail to %(email)s.', email=form.email.data), 'info') else: flash( _('Failed to send account details to %(email)s.', email=form.email.data), 'error') if hasattr(form, 'continue_') and form.continue_.data == 'yes': return redirect(url_for('user_insert')) return redirect(url_for('user_view', id_=user_id)) return render_template( 'user/insert.html', form=form, title=_('user'), crumbs=[[_('admin'), f"{url_for('admin_index')}#tab-user"], f"+ {uc_first(_('user'))}"])
def reset_password(): if current_user.is_authenticated: # Prevent password reset if already logged in return redirect(url_for('index')) form = PasswordResetForm() if form.validate_on_submit() and session['settings']['mail']: # pragma: no cover user = UserMapper.get_by_email(form.email.data) if not user: logger.log('info', 'password', 'Password reset for non existing ' + form.email.data) flash(_('error non existing email'), 'error') else: code = UserMapper.generate_password() user.password_reset_code = code user.password_reset_date = datetime.datetime.now() user.update() link = request.scheme + '://' + request.headers['Host'] link += url_for('reset_confirm', code=code) subject = _('Password reset request for %(site_name)s', site_name=session['settings']['site_name']) body = _('We received a password reset request for %(username)s', username=user.username) body += ' ' + _('at') + ' ' body += request.headers['Host'] + '\n\n' + _('reset password link') + ':\n\n' body += link + '\n\n' + _('The link is valid for') + ' ' body += str(session['settings']['reset_confirm_hours']) + ' ' + _('hours') + '.' if send_mail(subject, body, form.email.data): flash(_('A password reset confirmation mail was send to %(email)s.', email=form.email.data), 'info') else: flash(_('Failed to send password reset confirmation mail to %(email)s.', email=form.email.data), 'error') return redirect(url_for('login')) return render_template('login/reset_password.html', form=form)
def reset_confirm(code): # pragma: no cover user = UserMapper.get_by_reset_code(code) if not user: logger.log('info', 'auth', 'unknown reset code') flash(_('invalid password reset confirmation code'), 'error') abort(404) hours = session['settings']['reset_confirm_hours'] if datetime.datetime.now() > user.password_reset_date + datetime.timedelta(hours=hours): logger.log('info', 'auth', 'reset code expired') flash(_('This reset confirmation code has expired.'), 'error') abort(404) password = UserMapper.generate_password() user.password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') user.password_reset_code = None user.password_reset_date = None user.login_failed_count = 0 user.update() subject = _('New password for %(sitename)s', sitename=session['settings']['site_name']) body = _('New password for %(username)s', username=user.username) + ' ' body += _('at') + ' ' + request.scheme + '://' + request.headers['Host'] + ':\n\n' body += uc_first(_('username')) + ': ' + user.username + '\n' body += uc_first(_('password')) + ': ' + password + '\n' if send_mail(subject, body, user.email, False): flash(_('Send new password mail to %(email)s.', email=user.email), 'info') else: flash(_('Failed to send password mail to %(email)s.', email=user.email), 'error') return redirect(url_for('login'))
def reset_confirm(code: str) -> Response: # pragma: no cover user = User.get_by_reset_code(code) if not user or not user.username or not user.email: logger.log('info', 'auth', 'unknown reset code') flash(_('invalid password reset confirmation code'), 'error') abort(404) hours = g.settings['reset_confirm_hours'] if datetime.datetime.now() > \ user.password_reset_date + datetime.timedelta(hours=hours): logger.log('info', 'auth', 'reset code expired') flash(_('This reset confirmation code has expired.'), 'error') abort(404) password = User.generate_password() user.password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') user.password_reset_code = None user.password_reset_date = None user.login_failed_count = 0 user.update() subject = \ _('New password for %(sitename)s', sitename=g.settings['site_name']) body = _('New password for %(username)s', username=user.username) + ' ' body += f"{_('at')} {request.scheme}://{request.headers['Host']}:\n\n" body += f"{uc_first(_('username'))}: {user.username}\n" body += f"{uc_first(_('password'))}: {password}\n" if send_mail(subject, body, user.email, False): flash(_('A new password was sent to %(email)s.', email=user.email), 'info') else: flash( _('Failed to send password mail to %(email)s.', email=user.email), 'error') return redirect(url_for('login'))
def admin_newsletter(): form = NewsLetterForm() if form.validate_on_submit(): # pragma: no cover recipients = 0 for user_id in (request.form.getlist('recipient')): user = UserMapper.get_by_id(user_id) if user.settings['newsletter'] and user.active: code = UserMapper.generate_password() user.unsubscribe_code = code user.update() link_ = request.scheme + '://' + request.headers['Host'] link_ += url_for('index_unsubscribe', code=code) unsubscribe = '\n\n' + _( 'To unsubscribe use the link below.') + '\n\n' + link_ if send_mail(form.subject.data, form.body.data + unsubscribe, user.email): recipients += 1 flash(_('Newsletter send') + ': ' + str(recipients), 'info') return redirect(url_for('admin_index')) table = { 'id': 'user', 'header': ['username', 'email', 'receiver'], 'data': [] } for user in UserMapper.get_all(): if user.settings['newsletter'] and user.active: # pragma: no cover checkbox = '<input value="' + str(user.id) + '" name="recipient"' checkbox += ' type="checkbox" checked="checked">' table['data'].append([user.username, user.email, checkbox]) return render_template('admin/newsletter.html', form=form, table=table)
def settings_index(): form = TestMail() if form.validate_on_submit( ) and session['settings']['mail']: # pragma: no cover user = current_user subject = _('Test mail from %(site_name)s', site_name=session['settings']['site_name']) body = _('This test mail was sent by %(username)s', username=user.username) body += ' ' + _('at') + ' ' + request.headers['Host'] if send_mail(subject, body, form.receiver.data): flash( _('A test mail was sent to %(email)s.', email=form.receiver.data)) else: form.receiver.data = current_user.email settings = session['settings'] groups = OrderedDict([ ('general', OrderedDict([(_('site name'), settings['site_name']), (_('default language'), app.config['LANGUAGES'][settings['default_language']]), (_('default table rows'), settings['default_table_rows']), (_('log level'), app.config['LOG_LEVELS'][int(settings['log_level'])]), (_('debug mode'), uc_first(_('on')) if settings['debug_mode'] else uc_first(_('off')))])), ('mail', OrderedDict([ (_('mail'), uc_first(_('on')) if settings['mail'] else uc_first(_('off'))), (_('mail transport username'), settings['mail_transport_username']), (_('mail transport host'), settings['mail_transport_host']), (_('mail transport port'), settings['mail_transport_port']), (_('mail from email'), settings['mail_from_email']), (_('mail from name'), settings['mail_from_name']), (_('mail recipients feedback'), ';'.join(settings['mail_recipients_feedback'])) ])), ('authentication', OrderedDict([ (_('random password length'), settings['random_password_length']), (_('minimum password length'), settings['minimum_password_length']), (_('reset confirm hours'), settings['reset_confirm_hours']), (_('failed login tries'), settings['failed_login_tries']), (_('failed login forget minutes'), settings['failed_login_forget_minutes']) ])) ]) return render_template('settings/index.html', groups=groups, settings=settings, form=form)
def admin_newsletter() -> Union[str, Response]: class NewsLetterForm(FlaskForm): subject = StringField( '', [InputRequired()], render_kw={ 'placeholder': uc_first(_('subject')), 'autofocus': True}) body = TextAreaField( '', [InputRequired()], render_kw={'placeholder': uc_first(_('content'))}) save = SubmitField(_('send')) form = NewsLetterForm() form.save.label.text = uc_first(_('send')) if form.validate_on_submit(): # pragma: no cover count = 0 for user_id in request.form.getlist('recipient'): user = User.get_by_id(user_id) if user \ and user.settings['newsletter'] \ and user.active \ and user.email: code = User.generate_password() user.unsubscribe_code = code user.update() link_ = f"{request.scheme}://{request.headers['Host']}" link_ += url_for('index_unsubscribe', code=code) if send_mail( form.subject.data, f'{form.body.data}\n\n' f'{_("To unsubscribe use the link below.")}\n\n' f'{link_}', user.email): count += 1 flash(f"{_('Newsletter send')}: {count}", 'info') return redirect(url_for('admin_index')) table = Table(['username', 'email', 'receiver']) for user in User.get_all(): if user \ and user.settings['newsletter'] \ and user.active: # pragma: no cover table.rows.append([ user.username, user.email, f'<input value="{user.id}" name="recipient" type="checkbox" ' f'checked="checked">']) return render_template( 'admin/newsletter.html', form=form, table=table, title=_('newsletter'), crumbs=[ [_('admin'), f"{url_for('admin_index')}#tab-user"], _('newsletter')])
def index_feedback() -> str: form = FeedbackForm() if form.validate_on_submit() and session['settings']['mail']: # pragma: no cover subject = form.subject.data + ' from ' + session['settings']['site_name'] user = current_user body = form.subject.data + ' from ' + user.username + ' (' + str(user.id) + ') ' body += user.email + ' at ' + request.headers['Host'] + "\n\n" + form.description.data if send_mail(subject, body, session['settings']['mail_recipients_feedback']): flash(_('info feedback thanks'), 'info') else: flash(_('error mail send'), 'error') return redirect(url_for('index')) return render_template('index/feedback.html', form=form)
def index_feedback(): form = FeedbackForm() if form.validate_on_submit() and session['settings']['mail']: # pragma: no cover subject = form.subject.data + ' from ' + session['settings']['site_name'] user = current_user body = form.subject.data + ' from ' + user.username + ' (' + str(user.id) + ') ' body += user.email + ' at ' + request.headers['Host'] + "\n\n" + form.description.data if send_mail(subject, body, session['settings']['mail_recipients_feedback']): flash(_('info feedback thanks'), 'info') else: flash(_('error mail send'), 'error') return redirect(url_for('index')) return render_template('index/feedback.html', form=form)
def reset_password() -> Union[str, Response]: if current_user.is_authenticated: # Prevent password reset if logged in return redirect(url_for('overview')) form = PasswordResetForm() if form.validate_on_submit() \ and session['settings']['mail']: # pragma: no cover user = User.get_by_email(form.email.data) if not user: logger.log('info', 'password', f'Password reset for non existing {form.email.data}') flash(_('error non existing email'), 'error') else: code = User.generate_password() user.password_reset_code = code user.password_reset_date = datetime.datetime.now() user.update() url = url_for('reset_confirm', code=code) link = f"{request.scheme}://{request.headers['Host']}{url}" subject = _('Password reset request for %(site_name)s', site_name=session['settings']['site_name']) body = _('We received a password reset request for %(username)s', username=user.username) body += \ f" {_('at')} {request.headers['Host']}\n\n" \ f"{_('reset password link')}:\n\n" \ f"{link}\n\n" \ f"{_('The link is valid for')} " \ f"{session['settings']['reset_confirm_hours']} {_('hours')}." email = form.email.data if send_mail(subject, body, form.email.data): flash( _( 'A password reset confirmation mail was send ' 'to %(email)s.', email=email), 'info') else: flash( _( 'Failed to send password reset confirmation mail ' 'to %(email)s.', email=email), 'error') return redirect(url_for('login')) return render_template('login/reset_password.html', form=form, crumbs=[[_('login'), url_for('login')], _('Forgot your password?')])
def index_feedback() -> Union[str, Response]: form = FeedbackForm() if form.validate_on_submit() and g.settings['mail']: # pragma: no cover body = \ f'{form.subject.data} from {current_user.username} ' \ f'({current_user.id}) {current_user.email} at ' \ f'{request.headers["Host"]}\n\n' \ f'{form.description.data}' if send_mail( f"{uc_first(form.subject.data)} from {g.settings['site_name']}", body, g.settings['mail_recipients_feedback']): flash(_('info feedback thanks'), 'info') else: flash(_('error mail send'), 'error') return redirect(url_for('overview')) return render_template('index/feedback.html', form=form, title=_('feedback'), crumbs=[_('feedback')])
def admin_mail() -> str: form = TestMailForm() settings = session['settings'] if form.validate_on_submit() and session['settings']['mail']: # pragma: no cover user = current_user subject = _('Test mail from %(site_name)s', site_name=session['settings']['site_name']) body = _('This test mail was sent by %(username)s', username=user.username) body += ' ' + _('at') + ' ' + request.headers['Host'] if send_mail(subject, body, form.receiver.data): flash(_('A test mail was sent to %(email)s.', email=form.receiver.data)) else: form.receiver.data = current_user.email mail_settings = OrderedDict([ (_('mail'), uc_first(_('on')) if settings['mail'] else uc_first(_('off'))), (_('mail transport username'), settings['mail_transport_username']), (_('mail transport host'), settings['mail_transport_host']), (_('mail transport port'), settings['mail_transport_port']), (_('mail from email'), settings['mail_from_email']), (_('mail from name'), settings['mail_from_name']), (_('mail recipients feedback'), ';'.join(settings['mail_recipients_feedback']))]) return render_template('admin/mail.html', settings=settings, mail_settings=mail_settings, form=form)
def reset_password() -> str: if current_user.is_authenticated: # Prevent password reset if already logged in return redirect(url_for('index')) form = PasswordResetForm() if form.validate_on_submit( ) and session['settings']['mail']: # pragma: no cover user = UserMapper.get_by_email(form.email.data) if not user: logger.log('info', 'password', 'Password reset for non existing ' + form.email.data) flash(_('error non existing email'), 'error') else: code = UserMapper.generate_password() user.password_reset_code = code user.password_reset_date = datetime.datetime.now() user.update() link = request.scheme + '://' + request.headers['Host'] link += url_for('reset_confirm', code=code) subject = _('Password reset request for %(site_name)s', site_name=session['settings']['site_name']) body = _('We received a password reset request for %(username)s', username=user.username) body += ' ' + _('at') + ' ' body += request.headers['Host'] + '\n\n' + _( 'reset password link') + ':\n\n' body += link + '\n\n' + _('The link is valid for') + ' ' body += str(session['settings']['reset_confirm_hours']) + ' ' + _( 'hours') + '.' if send_mail(subject, body, form.email.data): flash( _('A password reset confirmation mail was send to %(email)s.', email=form.email.data), 'info') else: flash( _('Failed to send password reset confirmation mail to %(email)s.', email=form.email.data), 'error') return redirect(url_for('login')) return render_template('login/reset_password.html', form=form)
def admin_newsletter() -> Union[str, Response]: form = NewsLetterForm() form.save.label.text = uc_first(_('send')) if form.validate_on_submit(): # pragma: no cover recipients = 0 for user_id in (request.form.getlist('recipient')): user = User.get_by_id(user_id) if user and user.settings[ 'newsletter'] and user.active and user.email: code = User.generate_password() user.unsubscribe_code = code user.update() link_ = request.scheme + '://' + request.headers['Host'] link_ += url_for('index_unsubscribe', code=code) unsubscribe = '\n\n' + _( 'To unsubscribe use the link below.') + '\n\n' + link_ if send_mail(form.subject.data, form.body.data + unsubscribe, user.email): recipients += 1 flash(_('Newsletter send') + ': ' + str(recipients), 'info') return redirect(url_for('admin_index')) table = Table(['username', 'email', 'receiver']) for user in User.get_all(): if user and user.settings[ 'newsletter'] and user.active: # pragma: no cover table.rows.append([ user.username, user.email, '<input value="{id}" name="recipient" type="checkbox" checked="checked">' .format(id=user.id) ]) return render_template( 'admin/newsletter.html', form=form, table=table, title=_('newsletter'), crumbs=[[_('admin'), url_for('admin_index') + '#tab-user'], _('newsletter')])
def admin_index(action: Optional[str] = None, id_: Optional[int] = None) -> Union[str, Response]: if is_authorized('manager'): if id_ and action == 'delete_user': user = User.get_by_id(id_) if not user \ or user.id == current_user.id \ or (user.group == 'admin' and not is_authorized('admin')): abort(403) User.delete(id_) flash(_('user deleted'), 'info') elif action == 'remove_logo': Settings.set_logo() return redirect(f"{url_for('admin_index')}#tab-file") tables = { 'user': Table([ 'username', 'name', 'group', 'email', 'newsletter', 'created', 'last login', 'entities' ], defs=[{ 'className': 'dt-body-right', 'targets': 7 }]), 'content': Table(['name'] + list(app.config['LANGUAGES'])) } for user in User.get_all(): count = User.get_created_entities_count(user.id) email = user.email \ if is_authorized('manager') or user.settings['show_email'] else '' tables['user'].rows.append([ link(user), user.real_name, user.group, email, _('yes') if user.settings['newsletter'] else '', format_date(user.created), format_date(user.login_last_success), format_number(count) if count else '' ]) for item, languages in get_content().items(): content = [uc_first(_(item))] for language in app.config['LANGUAGES']: content.append(sanitize(languages[language], 'text')) content.append(link(_('edit'), url_for('admin_content', item=item))) tables['content'].rows.append(content) form = None if is_authorized('admin'): form = TestMailForm() if form.validate_on_submit( ) and g.settings['mail']: # pragma: no cover subject = _('Test mail from %(site_name)s', site_name=g.settings['site_name']) body = _('This test mail was sent by %(username)s', username=current_user.username) body += f" {_('at')} '{request.headers['Host']}" if send_mail(subject, body, form.receiver.data): flash( _('A test mail was sent to %(email)s.', email=form.receiver.data), 'info') else: form.receiver.data = current_user.email tabs = { 'files': Tab(_('files'), buttons=[ manual('entity/file'), button(_('edit'), url_for('admin_settings', category='files')) if is_authorized('manager') else '', button(_('list'), url_for('index', view='file')), button(_('file'), url_for('insert', class_='file')) ], content=render_template('admin/file.html', info=get_form_settings(FilesForm()), disk_space_info=get_disk_space_info())), 'user': Tab(_('user'), table=tables['user'], buttons=[ manual('admin/user'), button(_('activity'), url_for('user_activity')), button(_('newsletter'), url_for('admin_newsletter')) if is_authorized('manager') and g.settings['mail'] else '', button(_('user'), url_for('user_insert')) if is_authorized('manager') else '' ]) } if is_authorized('admin'): tabs['general'] = Tab( 'general', content=display_info(get_form_settings(GeneralForm())), buttons=[ manual('admin/general'), button(_('edit'), url_for('admin_settings', category='general')), button(_('system log'), url_for('admin_log')) ]) tabs['email'] = Tab( 'email', content=display_info(get_form_settings(MailForm())), buttons=[ manual('admin/mail'), button(_('edit'), url_for('admin_settings', category='mail')) ]) if g.settings['mail']: tabs['email'].content += display_form(form) if is_authorized('manager'): tabs['modules'] = Tab(_('modules'), content=f""" <h1>{_('Defaults for new user')}</h1> {display_info(get_form_settings(ModulesForm()))}""", buttons=[ manual('admin/modules'), button( _('edit'), url_for('admin_settings', category='modules')) ]) tabs['map'] = Tab('map', content=display_info(get_form_settings(MapForm())), buttons=[ manual('admin/map'), button(_('edit'), url_for('admin_settings', category='map')) ]) tabs['content'] = Tab('content', content=tables['content'].display(), buttons=[manual('admin/content')]) if is_authorized('contributor'): tabs['data'] = Tab('data', content=render_template( 'admin/data.html', imports=Import.get_all_projects(), info=get_form_settings(ApiForm()))) return render_template('tabs.html', tabs=tabs, title=_('admin'), crumbs=[_('admin')])
def admin_index(action: Optional[str] = None, id_: Optional[int] = None) -> Union[str, Response]: if is_authorized('manager'): if id_ and action == 'delete_user': user = User.get_by_id(id_) if not user \ or user.id == current_user.id \ or (user.group == 'admin' and not is_authorized('admin')): abort(403) # pragma: no cover User.delete(id_) flash(_('user deleted'), 'info') elif action == 'remove_logo': Settings.set_logo() return redirect(url_for('admin_index') + '#tab-file') dirs = { 'uploads': True if os.access(app.config['UPLOAD_DIR'], os.W_OK) else False, 'export/sql': True if os.access(app.config['EXPORT_DIR'] / 'sql', os.W_OK) else False, 'export/csv': True if os.access(app.config['EXPORT_DIR'] / 'csv', os.W_OK) else False } tables = { 'user': Table([ 'username', 'name', 'group', 'email', 'newsletter', 'created', 'last login', 'entities' ]), 'content': Table(['name'] + [language for language in app.config['LANGUAGES'].keys()]) } for user in User.get_all(): count = User.get_created_entities_count(user.id) email = user.email if is_authorized( 'manager') or user.settings['show_email'] else '' tables['user'].rows.append([ link(user), user.real_name, user.group, email, _('yes') if user.settings['newsletter'] else '', format_date(user.created), format_date(user.login_last_success), format_number(count) if count else '' ]) for item, languages in Content.get_content().items(): content = [uc_first(_(item))] for language in app.config['LANGUAGES'].keys(): content.append(sanitize(languages[language], 'text')) content.append(link(_('edit'), url_for('admin_content', item=item))) tables['content'].rows.append(content) form = None if is_authorized('admin'): form = TestMailForm() if form.validate_on_submit( ) and session['settings']['mail']: # pragma: no cover subject = _('Test mail from %(site_name)s', site_name=session['settings']['site_name']) body = _('This test mail was sent by %(username)s', username=current_user.username) body += ' ' + _('at') + ' ' + request.headers['Host'] if send_mail(subject, body, form.receiver.data): flash( _('A test mail was sent to %(email)s.', email=form.receiver.data), 'info') else: form.receiver.data = current_user.email return render_template('admin/index.html', form=form, tables=tables, settings=session['settings'], writeable_dirs=dirs, disk_space_info=get_disk_space_info(), imports=Import.get_all_projects(), title=_('admin'), crumbs=[_('admin')], info={ 'file': get_form_settings(FilesForm()), 'general': get_form_settings(GeneralForm()), 'mail': get_form_settings(MailForm()), 'map': get_form_settings(MapForm()), 'api': get_form_settings(ApiForm()), 'modules': get_form_settings(ModulesForm()) })