def initialize_user_component(app): # Initialize the Admin # URL describes through which address we access the page. # Endpoint enables us to do url_for('userp') to yield the URL url = '/user' admin = Admin(index_view=HomeView(url=url, endpoint='user', name=lazy_gettext("Home")), name=lazy_gettext("User Profile"), url=url, endpoint="home-user") # admin.add_view(ProfileEditView(name=lazy_gettext("Profile"), url='profile', endpoint='user.profile')) admin.add_view(AppsView(name=lazy_gettext("Apps"), url="apps", endpoint='user.apps')) admin.init_app(app)
def initialize_admin_component(app): # Initialize the Admin # URL describes through which address we access the page. # Endpoint enables us to do url_for('userp') to yield the URL url = '/admin' admin = Admin(index_view = AdminView(url = url, endpoint = 'admin'), name=lazy_gettext('Admin Profile'), endpoint = "home-admin") admin.add_view(UsersView(name=lazy_gettext('Users'), url = 'users', endpoint = 'admin.users')) admin.add_view(AdminAppsView(name=lazy_gettext('Apps'), url = 'apps-admin', endpoint = 'admin.admin-apps')) admin.add_view(RedirectView('user.profile.index', name=lazy_gettext('My Profile'), url = 'profile', endpoint = 'admin.profile')) admin.add_view(RedirectView('index', name=lazy_gettext('Back'), url = 'back', endpoint = 'admin.back')) admin.init_app(app)
class ApplicationForm(Form): name = TextField(lazy_gettext("Name:"), validators=[required()], widget=AngularJSTextInput(ng_enter="submitForm()")) url = URLField(lazy_gettext("Web:"), validators=[required()], widget=AngularJSURLInput(ng_model='embed.url', ng_enter="submitForm()")) height = HiddenField(lazy_gettext("Height:"), validators=[required()], widget=AngularJSHiddenInput(ng_model='embed.height')) scale = HiddenField(lazy_gettext("Scale:"), validators=[required()], widget=AngularJSHiddenInput(ng_model='embed.scale'))
def initialize_user_component(app): # Initialize the Admin # URL describes through which address we access the page. # Endpoint enables us to do url_for('userp') to yield the URL url = '/user' admin = Admin(index_view=HomeView(url=url, endpoint='user', name=lazy_gettext("Home")), name=lazy_gettext("User Profile"), url=url, endpoint="home-user") # admin.add_view(ProfileEditView(name=lazy_gettext("Profile"), url='profile', endpoint='user.profile')) admin.add_view( AppsView(name=lazy_gettext("Apps"), url="apps", endpoint='user.apps')) admin.init_app(app)
class ProfileEditForm(Form): """ The form used for the Profile Edit view. """ name = DisabledTextField(lazy_gettext(u"Name:")) login = DisabledTextField(lazy_gettext(u"Login:"******"E-mail:")) password = PasswordField( lazy_gettext(u"Password:"******"password_rep", message="Passwords must match")]) password_rep = PasswordField(lazy_gettext(u"Password again:")) organization = TextField(lazy_gettext(u"Organization:")) role = TextField(lazy_gettext(u"Role:")) creation_date = DisabledTextField(lazy_gettext(u"Creation date:")) last_access_date = DisabledTextField(lazy_gettext(u"Last access:")) auth_system = TextField(lazy_gettext(u"Auth system:"))
def create_model(self, form): if form.auth_data.data == '': form.auth_data.errors.append(lazy_gettext("This field is required.")) return False form.auth_data.data = create_salted_password(form.auth_data.data) model = super(UsersView, self).create_model(form) model.creation_date = datetime.datetime.now() return model
def create_model(self, form): if form.auth_data.data == '': form.auth_data.errors.append( lazy_gettext("This field is required.")) return False form.auth_data.data = create_salted_password(form.auth_data.data) model = super(UsersView, self).create_model(form) model.creation_date = datetime.datetime.now() return model
def adapt_duplicate(appid): app = get_app(appid) if app is None: return render_template("composers/errors.html", message="Application not found") form = DuplicationForm() if form.validate_on_submit(): # Protect against CSRF attacks. if not verify_csrf(request): return render_template( "composers/errors.html", message= "Request does not seem to come from the right source (csrf check)" ), 400 existing_app = get_app_by_name(form.name.data) if existing_app: if not form.name.errors: form.name.errors = [] form.name.errors.append( lazy_gettext("You already have an application with this name")) else: new_app = create_app(form.name.data, 'adapt', app.spec.url, app.data) for appvar in app.appvars: # Copy every appvar for the original app as well. add_var(new_app, appvar.name, appvar.value) return redirect(url_for('.adapt_edit', appid=new_app.unique_id)) if not form.name.data: counter = 2 potential_name = '' while counter < 1000: potential_name = '%s (%s)' % (app.name, counter) existing_app = get_app_by_name(potential_name) if not existing_app: break counter += 1 form.name.data = potential_name return render_template("composers/adapt/duplicate.html", form=form, app=app)
def adapt_duplicate(appid): app = get_app(appid) if app is None: return render_template("composers/errors.html", message="Application not found") form = DuplicationForm() if form.validate_on_submit(): # Protect against CSRF attacks. if not verify_csrf(request): return render_template("composers/errors.html", message="Request does not seem to come from the right source (csrf check)"), 400 existing_app = get_app_by_name(form.name.data) if existing_app: if not form.name.errors: form.name.errors = [] form.name.errors.append(lazy_gettext("You already have an application with this name")) else: new_app = create_app(form.name.data, 'adapt', app.spec.url, app.data) for appvar in app.appvars: # Copy every appvar for the original app as well. add_var(new_app, appvar.name, appvar.value) return redirect(url_for('.adapt_edit', appid=new_app.unique_id)) if not form.name.data: counter = 2 potential_name = '' while counter < 1000: potential_name = '%s (%s)' % (app.name, counter) existing_app = get_app_by_name(potential_name) if not existing_app: break counter += 1 form.name.data = potential_name return render_template("composers/adapt/duplicate.html", form=form, app=app)
class AdminAppsView(AdminModelView): """ Admin Apps View. Basic entry view which lets us manage the applications located at the system. We will be able to filter, edit, and delete apps. The creation mode is disabled. """ # The creation mode is disabled can_create = False column_list = ('owner', 'unique_id', 'name', 'composer') column_labels = dict(owner=lazy_gettext('Owner'), unique_id=lazy_gettext('ID'), name=lazy_gettext('Name'), composer=lazy_gettext('Composer')) column_sortable_list = ('unique_id', 'name', 'composer') column_searchable_list = ('unique_id', 'name', 'composer') # column_filters = ('unique_id', 'name', 'composer', 'creation_date', 'modification_date', 'last_access_date') # Information needed when creating a new composer (not used at the moment) form_columns = ('owner', 'name', 'composer') sel_choices = [ (level, level.title()) for level in (lazy_gettext('translate'), lazy_gettext('adapt'), lazy_gettext('dummy')) ] # TODO: find where this is registered in case of activate the creation mode form_overrides = dict(composer=wtf.SelectField) form_args = dict(composer=dict(choices=sel_choices)) def __init__(self, **kwargs): super(AdminAppsView, self).__init__(models.App, db.session, **kwargs) # This function is used when deleting an app in the system def on_model_delete(self, model): # Delete every AppVar for that App #print "App Id: " + model.unique_id app = models.App.query.filter_by(unique_id=model.unique_id).first() models.AppVar.query.filter_by(app=app).delete()
import urllib2 import traceback from xml.dom import minidom from flask import render_template, request, flash, url_for, Response from flask_wtf import Form from wtforms import TextField from wtforms.validators import url, required from appcomposer.babel import gettext, lazy_gettext from appcomposer.composers.adapt.utils import shindig_url from appcomposer.utils import make_url_absolute, inject_absolute_urls, get_json, inject_original_url_in_xmldoc, inject_absolute_locales_in_xmldoc from appcomposer.composers.adapt import create_adaptor adaptor = create_adaptor(lazy_gettext('App adaptation'), initial={'url': None, 'configuration': None, 'configuration_name': None}, description=lazy_gettext("Create adaptations of customizable Go-Lab applications."), about_endpoint='jsconfig.about') CONFIG_DEFINITION_REGEX = re.compile(r"""(<\s*script[^<]*\sdata-configuration-definition(?:>|\s[^>]*>))""") SRC_REGEX = re.compile(r"""src\s*=\s*["']?([^"']+)["']?""") def find_definition_script(contents, url): data_config_definition_scripts = CONFIG_DEFINITION_REGEX.findall(contents) if len(data_config_definition_scripts) > 1: flash(gettext( "Too many scripts with data-configuration-definition found. This may happen if you have commented one. There can be a single one.")) elif len(data_config_definition_scripts) < 1:
# Required imports for a customized app view for the adapt tool (a possible block to be refactored?) from appcomposer.babel import lazy_gettext from appcomposer.login import requires_login info = { 'blueprint': 'adapt', 'url': '/composers/adapt', 'new_endpoint': 'adapt.adapt_appsearch', 'edit_endpoint': 'adapt.adapt_edit', 'create_endpoint': 'adapt.adapt_create', 'duplicate_endpoint': 'adapt.adapt_duplicate', 'delete_endpoint': 'dummy.delete', 'name': lazy_gettext('Adaptor Composer'), 'description': lazy_gettext('Adapt an existing app.') } adapt_blueprint = Blueprint(info['blueprint'], __name__) adaptors_blueprints = [] ADAPTORS = { # 'identifier' : { # 'initial' : function, # 'adaptor' : adaptor_object, # 'name' : 'Something', # 'description' : 'Description', # Optional # 'about_endpoint' : 'Flask endpoint', # Optional # } }
import urllib2 import traceback from xml.dom import minidom from flask import render_template, request, flash, url_for, Response from flask_wtf import Form from wtforms import TextField from wtforms.validators import url, required from appcomposer.babel import gettext, lazy_gettext from appcomposer.composers.adapt.utils import shindig_url from appcomposer.utils import make_url_absolute, inject_absolute_urls, get_json, inject_original_url_in_xmldoc, inject_absolute_locales_in_xmldoc from appcomposer.composers.adapt import create_adaptor adaptor = create_adaptor( lazy_gettext('App adaptation'), initial={ 'url': None, 'configuration': None, 'configuration_name': None }, description=lazy_gettext( "Create adaptations of customizable Go-Lab applications."), about_endpoint='jsconfig.about') CONFIG_DEFINITION_REGEX = re.compile( r"""(<\s*script[^<]*\sdata-configuration-definition(?:>|\s[^>]*>))""") SRC_REGEX = re.compile(r"""src\s*=\s*["']?([^"']+)["']?""") def find_definition_script(contents, url):
class UrlForm(Form): url = TextField(lazy_gettext(u'URL'), validators=[url(), required()])
class DuplicationForm(Form): name = TextField(lazy_gettext('Name'), validators=[Required(), Length(min=4)])
import appcomposer.appstorage.api as appstorage from appcomposer.babel import lazy_gettext, gettext info = { 'blueprint': 'dummy', 'url': '/composers/dummy', 'new_endpoint': 'dummy.new', 'edit_endpoint': 'dummy.edit', 'delete_endpoint': 'dummy.delete', 'name': lazy_gettext('Dummy Composer'), 'description': lazy_gettext( 'Pretend that you are composing an app. For testing purposes.') } dummy_blueprint = Blueprint(info['blueprint'], __name__) @dummy_blueprint.route("/") def dummy_index(): return render_template("composers/dummy/index.html") @dummy_blueprint.route("/delete", methods=["GET", "POST"]) def delete():
from flask import Blueprint from appcomposer.babel import lazy_gettext from forms import UrlForm info = { 'blueprint': 'translate', 'url': '/composers/translate', 'new_endpoint': 'translate.translate_index', 'edit_endpoint': 'translate.translate_selectlang', 'delete_endpoint': 'translate.translate_delete', 'name': lazy_gettext('Translate Composer'), 'description': lazy_gettext('Translate an existing app.') } translate_blueprint = Blueprint(info['blueprint'], __name__) # Maximum number of Apps that can have the same name. # Note that strictly speaking the name is never the same. # Repeated Apps have a (#number) appended to their name. CFG_SAME_NAME_LIMIT = 30 # These imports NEED to be after the translate_blueprint assignment due to # importing and cyclic dependencies issues. import view_editlang import view_selectlang import view_proposed_list
class UrlForm(Form): # TODO: use the url_validator again url = TextField(lazy_gettext(u'URL'), validators=[required()])
from flask import Blueprint, render_template, request, url_for, redirect, json, flash import appcomposer.appstorage.api as appstorage from appcomposer.babel import lazy_gettext, gettext info = { 'blueprint': 'dummy', 'url': '/composers/dummy', 'new_endpoint': 'dummy.new', 'edit_endpoint': 'dummy.edit', 'delete_endpoint': 'dummy.delete', 'name': lazy_gettext('Dummy Composer'), 'description': lazy_gettext('Pretend that you are composing an app. For testing purposes.') } dummy_blueprint = Blueprint(info['blueprint'], __name__) @dummy_blueprint.route("/") def dummy_index(): return render_template("composers/dummy/index.html") @dummy_blueprint.route("/delete", methods=["GET", "POST"]) def delete(): # If GET we display the confirmation screen and do not actually delete it. if request.method == "GET": appid = request.args.get("appid") if not appid: return "appid not provided", 400
def initialize_admin_component(app): # Initialize the Admin # URL describes through which address we access the page. # Endpoint enables us to do url_for('userp') to yield the URL url = '/admin' admin = Admin(index_view=AdminView(url=url, endpoint='admin'), name=lazy_gettext('Admin Profile'), endpoint="home-admin") category_users = lazy_gettext("Users") admin.add_view( UsersView(name=lazy_gettext('Regular Users'), category=category_users, url='users', endpoint='admin.users')) admin.add_view( GoLabOAuthUserView(name=lazy_gettext('Go-Lab Users'), category=category_users, url='golab_users', endpoint='admin.golab-users')) admin.add_view( AdminAppsView(name=lazy_gettext('Apps'), url='apps-admin', endpoint='admin.admin-apps')) admin.add_view( RedirectView('user.profile.index', name=lazy_gettext('My Profile'), url='profile', endpoint='admin.profile')) admin.add_view( RedirectView('index', name=lazy_gettext('Back'), url='back', endpoint='admin.back')) category_translator = lazy_gettext("Translator") admin.add_view( TranslationApplicationView(name=lazy_gettext('Translation apps'), category=category_translator, endpoint='admin.translation-apps')) admin.add_view( TranslationBundleView(name=lazy_gettext('Translation bundles'), category=category_translator, endpoint='admin.translation-bundles')) admin.add_view( TranslationMessageHistoryView(name=lazy_gettext('Translation history'), category=category_translator, endpoint='admin.translation-history')) admin.add_view( KeySuggestionsView(name=lazy_gettext('Suggestions by key'), category=category_translator, endpoint='admin.suggestions-key')) admin.add_view( ValueSuggestionsView(name=lazy_gettext('Suggestions by value'), category=category_translator, endpoint='admin.suggestions-value')) admin.add_view( ActiveTranslationMessageView(name=lazy_gettext('Active translations'), category=category_translator, endpoint='admin.active-translations')) admin.init_app(app)
class UsersView(AdminModelView): """ Users View. Entry view which lets us manage the users in the system. """ column_list = ('login', 'name', 'email', 'organization', 'role', 'login_as') column_formatters = dict(login_as=login_as_formatter) # column_filters = ('login', 'name', 'email', 'organization', 'role') column_labels = dict(login=lazy_gettext('Login'), name=lazy_gettext('Full Name'), email=lazy_gettext('E-mail'), organization=lazy_gettext('Organization'), role=lazy_gettext('Role'), login_as=lazy_gettext('Login as')) column_descriptions = dict( login=lazy_gettext('Username (all letters, dots and numbers)'), name=lazy_gettext('First and Last name'), email=lazy_gettext('Valid e-mail address'), login_as=lazy_gettext('Log in as you were that user')) # List of columns that can be sorted column_sortable_list = ('login', 'name', 'email', 'organization', 'role') # Columns that can used for searches column_searchable_list = ('login', 'name', 'email', 'organization', 'role') # Fields used for the creations of new users form_columns = ('login', 'name', 'email', 'organization', 'role', 'auth_system', 'auth_data') sel_choices = [] for role in ROLES: sel_choices.append((role, lazy_gettext(role).title())) auth_system_choices = [] auth_system_choices.append(('graasp', 'graasp')) auth_system_choices.append(('userpass', 'Regular')) form_overrides = dict(auth_system=wtf.SelectField, auth_data=PasswordField, role=wtf.SelectField) form_args = dict(email=dict(validators=[Email()]), login=dict(validators=[Regexp(LOGIN_REGEX)]), role=dict(choices=sel_choices), auth_system=dict(choices=auth_system_choices), auth_data=dict(validators=[Optional()])) def __init__(self, **kwargs): super(UsersView, self).__init__(models.User, db.session, **kwargs) @expose('/login_as/<login>/', methods=['GET', 'POST']) def login_as(self, login): if not _is_admin(): return "Something's going really wrong" if request.method == 'POST': login_as(login) return redirect(url_for('user.index')) return self.render("admin/login_as.html", login=login) def create_model(self, form): if form.auth_data.data == '': form.auth_data.errors.append( lazy_gettext("This field is required.")) return False form.auth_data.data = create_salted_password(form.auth_data.data) model = super(UsersView, self).create_model(form) model.creation_date = datetime.datetime.now() return model def update_model(self, form, model): old_auth_data = model.auth_data if form.auth_data.data != '': form.auth_data.data = create_salted_password(form.auth_data.data) return_value = super(UsersView, self).update_model(form, model) if form.auth_data.data == '': model.auth_data = old_auth_data self.session.add(model) self.session.commit() return return_value
from flask import render_template, request, flash, url_for, Response from flask_wtf import Form from wtforms import TextField from wtforms.validators import url as url_validator, required from appcomposer.babel import gettext, lazy_gettext from appcomposer.utils import make_url_absolute, inject_absolute_urls, get_json, inject_original_url_in_xmldoc, inject_absolute_locales_in_xmldoc from appcomposer.composers.adapt import create_adaptor adaptor = create_adaptor( 'Labs adaptation', initial={ 'url': None, 'configuration': None }, description=lazy_gettext( "Create adaptations of customizable gateway4labs laboratories."), about_endpoint='gateway4labs.about') SHINDIG_SERVER = 'http://shindig2.epfl.ch' def shindig_url(relative_url): return '%s%s' % (SHINDIG_SERVER, relative_url) def replace_default_configuration_script(contents, new_url): return DEFAULT_CONFIG_REGEX.sub( '<script data-configuration type="text/javascript" src="%s">' % new_url, contents)
import appcomposer.appstorage.api as appstorage from appcomposer.application import app # Required imports for a customized app view for the adapt tool (a possible block to be refactored?) from appcomposer.babel import lazy_gettext from appcomposer.login import requires_login info = { 'blueprint': 'adapt', 'url': '/composers/adapt', 'new_endpoint': 'adapt.adapt_appsearch', 'edit_endpoint': 'adapt.adapt_edit', 'create_endpoint': 'adapt.adapt_create', 'duplicate_endpoint': 'adapt.adapt_duplicate', 'delete_endpoint': 'dummy.delete', 'name': lazy_gettext('Adaptor Composer'), 'description': lazy_gettext('Adapt an existing app.') } adapt_blueprint = Blueprint(info['blueprint'], __name__) adaptors_blueprints = [] ADAPTORS = { # 'identifier' : { # 'initial' : function, # 'adaptor' : adaptor_object, # 'name' : 'Something', # 'description' : 'Description', # Optional # 'about_endpoint' : 'Flask endpoint', # Optional # } }
import urllib2 import traceback from xml.dom import minidom from flask import render_template, request, flash, url_for, Response from flask_wtf import Form from wtforms import TextField from wtforms.validators import url as url_validator, required from appcomposer.babel import gettext, lazy_gettext from appcomposer.utils import make_url_absolute, inject_absolute_urls, get_json, inject_original_url_in_xmldoc, inject_absolute_locales_in_xmldoc from appcomposer.composers.adapt import create_adaptor adaptor = create_adaptor('Labs adaptation', initial = {'url' : None, 'configuration' : None}, description = lazy_gettext("Create adaptations of customizable gateway4labs laboratories."), about_endpoint = 'gateway4labs.about') SHINDIG_SERVER = 'http://shindig2.epfl.ch' def shindig_url(relative_url): return '%s%s' % (SHINDIG_SERVER, relative_url) def replace_default_configuration_script(contents, new_url): return DEFAULT_CONFIG_REGEX.sub('<script data-configuration type="text/javascript" src="%s">' % new_url, contents) class UrlForm(Form): # TODO: use the url_validator again url = TextField(lazy_gettext(u'URL'), validators = [ required() ]) # labmanager_url = TextField(lazy_gettext(u'Labmanager URL'), validators = [ url_validator() ]) @adaptor.edit_route
def __call__(self, field, *args, **kwargs): visible = False for pos, registered_field in enumerate(local_data.fields): if field == registered_field and pos > 1: data = local_data.fields[pos - 1].data if data is not None: visible = data.auth_type.name != 'DB' self.hide_value = not visible resulting_input = super(VisiblePasswordWidget, self).__call__(field, *args, **kwargs) if visible: resulting_input = resulting_input.replace('password', 'text') resulting_input += '<br/><label class="checkbox"><input type="checkbox" onclick="javascript:flipInputVisibility(this);" %s>%s</input></label>' % (('checked' if visible else ''), lazy_gettext("Show")) return resulting_input