def change_accessibility(self): lab_id = int(request.form['lab_id']) activate = request.form['activate'] == 'true' lab = self.session.query(Laboratory).filter_by(id=lab_id).first() if lab is not None: if activate: lab.available = not activate lab.default_local_identifier = u"" else: local_id = request.form['default_local_identifier'] local_id = local_id.lstrip(' ') local_id = local_id.strip(' ') if not activate and len(local_id) == 0: flash(gettext("Invalid local identifier (empty)")) return redirect(url_for('.index_view')) existing_labs = self.session.query(Laboratory).filter_by( default_local_identifier=local_id).all() if len(existing_labs) > 0 and lab not in existing_labs: flash( gettext( u"Local identifier '%(localidentifier)s' already exists", localidentifier=local_id)) return redirect(url_for('.index_view')) lab.available = not activate lab.default_local_identifier = local_id self.session.add(lab) self.session.commit() return redirect(url_for('.index_view'))
def accessibility_formatter(v, c, lab, p): mylt = current_user.lt permission = db.session.query(PermissionToLt).filter_by(lt = mylt, laboratory = lab).first() if not permission: return gettext(u"Invalid permission") if permission.accessible: currently = gettext('This lab IS accesible') labaccessible = 'false' klass = 'btn-danger' msg = gettext('Make not accessible') else: currently = gettext(u'This lab is NOT accesible') labaccessible = 'true' klass = 'btn-success' msg = gettext('Make accessible') return Markup("""<form method='POST' action='%(url)s' style="text-align: center"> %(currently)s <BR> <input type='hidden' name='accessible_value' value='%(accessible_value)s'/> <input type='hidden' name='permission_to_lt_id' value='%(permission_id)s'/> <input class='btn %(klass)s' type='submit' value="%(msg)s"></input> </form>""" % dict( url = url_for('.change_accessibility'), accessible_value = labaccessible, permission_id = permission.id, klass = klass, msg = msg, currently = currently, ))
def parse_space_url(url): """ Given a Graasp URL, retrieve the space identifier (a number) """ # This is done in a different way if the space url ends with a number (the url contains space_) or if the url ends with a text (the url contains url=) if 'space_' in url: try: context_id = int(url.split('space_')[1]) except: raise Exception(gettext("Invalid format. Expected space_NUMBER")) else: return context_id elif 'url=' in url: try: space_name = url.split('url=')[1] json_file = 'http://graasp.epfl.ch/item3a/' + space_name + '.json' json_response = urllib2.urlopen(json_file) contents = json.loads(json_response.read()) context_id = contents['id'] return context_id except: raise Exception( gettext("Invalid format. Expected a valid Graasp space URL")) raise Exception( gettext( "Invalid format. Expected http://graasp.epfl.ch/#item=space_SOMETHING" ))
def app_xml(identifier): application = db.session.query(EmbedApplication).filter_by( identifier=identifier).first() if application is None: return render_template( "embed/error.xml", user=current_golab_user(), message=gettext("Application '{identifier}' not found").format( identifier=identifier)), 404 apps_per_language = {} languages = ['en'] for translation in application.translations: apps_per_language[translation.language] = { 'url': translation.url, 'full_url': translation.full_url, } languages.append(translation.language) author = application.owner.display_name response = make_response( render_template( "embed/app.xml", author=author, user=current_golab_user(), identifier=identifier, app=application, languages=languages, apps_per_language=apps_per_language, title=gettext("Application {name}").format(name=application.name))) response.content_type = 'application/xml' return response
def accessibility_formatter(v, c, lab, p): mylt = current_user.lt permission = db.session.query(PermissionToLt).filter_by( lt=mylt, laboratory=lab).first() if not permission: return gettext(u"Invalid permission") if permission.accessible: currently = gettext('This lab IS accesible') labaccessible = 'false' klass = 'btn-danger' msg = gettext('Make not accessible') else: currently = gettext(u'This lab is NOT accesible') labaccessible = 'true' klass = 'btn-success' msg = gettext('Make accessible') return Markup( """<form method='POST' action='%(url)s' style="text-align: center"> %(currently)s <BR> <input type='hidden' name='accessible_value' value='%(accessible_value)s'/> <input type='hidden' name='permission_to_lt_id' value='%(permission_id)s'/> <input class='btn %(klass)s' type='submit' value="%(msg)s"></input> </form>""" % dict( url=url_for('.change_accessibility'), accessible_value=labaccessible, permission_id=permission.id, klass=klass, msg=msg, currently=currently, ))
def login_admin(): """Login screen for application""" next = request.args.get('next', url_for('admin.index')) if request.method == 'GET': return render_template('login_admin.html', next=next) if request.method == 'POST' and 'username' in request.form: username = request.form['username'] hashed = unicode( new_hash(ALGORITHM, request.form['password'].encode('utf8')).hexdigest()) user = LabManagerUser.exists(username, hashed) if user is not None: if login_user(user): session['loggeduser'] = username session['last_request'] = time() session['usertype'] = 'labmanager' next = request.args.get('next', url_for('admin.index')) return redirect(next) else: flash(gettext(u'Could not log in.')) return render_template('login_admin.html', next=next) else: flash(gettext(u'Invalid username.')) return render_template('login_admin.html', next=next) return gettext("Error in create_session")
def launch_experiment(): consumer_key = session.get('consumer') if consumer_key is None: return gettext("consumer key not found") permission_to_lt_user = PermissionToLtUser.find(key = consumer_key) if permission_to_lt_user is None: return gettext("permission not found") p_to_lt = permission_to_lt_user.permission_to_lt courses_configurations = [] # No such concept in the LTI version request_payload = {} # This could be populated in the HTML. Pending. lt_configuration = p_to_lt.configuration db_laboratory = p_to_lt.laboratory db_rlms = db_laboratory.rlms author = session.get('author_identifier', '(not in session)') referer = request.referrer ManagerClass = get_manager_class(db_rlms.kind, db_rlms.version) remote_laboratory = ManagerClass(db_rlms.configuration) response = remote_laboratory.reserve(db_laboratory.laboratory_id, author, p_to_lt.lt.name, lt_configuration, courses_configurations, request_payload, { 'user_agent' : unicode(request.user_agent), 'from_ip' : request.remote_addr, 'referer' : referer, }) load_url = response['load_url'] return redirect(load_url)
def register(): form = RegistrationForm() if form.validate_on_submit(): errors = False if db.session.query(LearningTool).filter_by(name = form.short_name.data).first(): form.short_name.errors.append(gettext('This name is already taken')) errors = True if db.session.query(LearningTool).filter_by(full_name = form.full_name.data).first(): form.full_name.errors.append(gettext('This name is already taken')) errors = True if not errors: lt = LearningTool(name = form.short_name.data, full_name = form.full_name.data, url = form.url.data) shindig_credentials = ShindigCredentials(lt = lt, shindig_url = 'http://shindig2.epfl.ch') lt_user = LtUser(login = form.user_login.data, full_name = form.user_full_name.data, lt = lt, access_level = 'admin') lt_user.password = unicode(hashlib.new(ALGORITHM, form.user_password.data.encode('utf8')).hexdigest()) for lab in db.session.query(Laboratory).filter_by(available = True).all(): permission_to_lt = PermissionToLt(lt = lt, laboratory = lab, local_identifier = lab.default_local_identifier) db.session.add(permission_to_lt) db.session.add(lt) db.session.add(shindig_credentials) db.session.add(lt_user) db.session.commit() return redirect(url_for('login_ple', next = url_for('ple_admin.index')) ) return render_template("opensocial/registration.html", form = form)
def change_public_availability(self): lab_id = int(request.form['lab_id']) activate = request.form['activate'] == "true" lab = self.session.query(Laboratory).filter_by(id=lab_id).first() if lab is not None: if activate: lab.publicly_available = not activate lab.public_identifier = u"" else: public_id = request.form['public_identifier'] public_id = public_id.lstrip(' ') public_id = public_id.strip(' ') if not activate and len(public_id) == 0: flash(gettext("Invalid public identifier (empty)")) return redirect(url_for('.index_view')) existing_labs = self.session.query(Laboratory).filter_by( public_identifier=public_id).all() if len(existing_labs) > 0 and lab not in existing_labs: flash( gettext( u"Public identifier '%(publicidentifier)s' already exists", publicidentifier=public_id)) return redirect(url_for('.index_view')) lab.publicly_available = not activate lab.public_identifier = public_id self.session.add(lab) self.session.commit() return redirect(url_for('.index_view'))
def _open_widget_impl(lab_name, widget_name, public_lab = False, public_rlms = False, institution_id = None, rlms_identifier = None): if public_rlms: db_rlms = db.session.query(RLMS).filter_by(publicly_available = True, public_identifier = rlms_identifier).first() if db_rlms is None: return gettext("RLMS not found") else: if public_lab: db_laboratory = db.session.query(Laboratory).filter_by(publicly_available = True, public_identifier = lab_name).first() else: institution = db.session.query(LearningTool).filter_by(name = institution_id).first() if institution is None or len(institution.shindig_credentials) == 0: return gettext("Institution not found or it does not support Shindig") permission = db.session.query(PermissionToLt).filter_by(lt = institution, local_identifier = lab_name).first() db_laboratory = permission.laboratory if permission is not None else None if db_laboratory is None: return gettext("Laboratory not found") db_rlms = db_laboratory.rlms rlms_version = db_rlms.version rlms_kind = db_rlms.kind ManagerClass = get_manager_class(rlms_kind, rlms_version, db_rlms.id) remote_laboratory = ManagerClass(db_rlms.configuration) reservation_id = request.args.get('reservation_id') or 'reservation-id-not-found' locale = request.args.get('locale') or None kwargs = {} if locale: kwargs['locale'] = locale if Capabilities.WIDGET in remote_laboratory.get_capabilities(): response = remote_laboratory.load_widget(reservation_id, widget_name, back = url_for('.reload', _external = True), **kwargs) else: response = {'url' : reservation_id} widget_contents_url = response['url'] return redirect(widget_contents_url)
def login_admin(): """Login screen for application""" next = request.args.get('next',url_for('admin.index')) if request.method == 'GET': return render_template('login_admin.html', next=next) if request.method == 'POST' and 'username' in request.form: username = request.form['username'] hashed = unicode(new_hash(ALGORITHM, request.form['password'].encode('utf8')).hexdigest()) user = LabManagerUser.exists(username, hashed) if user is not None: if login_user(user): session['loggeduser'] = username session['last_request'] = time() session['usertype'] = 'labmanager' next = request.args.get('next', url_for('admin.index')) return redirect(next) else: flash(gettext(u'Could not log in.')) return render_template('login_admin.html', next=next) else: flash(gettext(u'Invalid username.')) return render_template('login_admin.html', next=next) return gettext("Error in create_session")
def login_lms(): """Login screen for application""" DEFAULT_NEXT = url_for('lms_admin.index') next = request.args.get('next', DEFAULT_NEXT) print next lmss = [ lt for lt in LearningTool.all() if len(lt.shindig_credentials) == 0 ] if request.method == 'GET': return render_template('login_lms.html', next=next, lmss=lmss, action_url = url_for('login_lms')) if request.method == 'POST' and 'username' in request.form: username = request.form['username'] hashed = unicode(new_hash(ALGORITHM, request.form['password'].encode('utf8')).hexdigest()) lms_id = request.form['lms'] user = LtUser.exists(username, hashed, lms_id) if user is not None: if login_user(user): session['loggeduser'] = username session['last_request'] = time() session['usertype'] = 'lms' if next == DEFAULT_NEXT: if user.access_level == 'instructor': next = url_for('lms_instructor.index') return redirect(next) else: flash(gettext(u'Could not log in.')) return render_template('login_lms.html', next=next, lmss=lmss, action_url = url_for('login_lms')) else: flash(gettext(u'Invalid username.')) return render_template('login_lms.html', next=next, lmss=lmss, action_url = url_for('login_lms')) return gettext("Error in create_session")
def password_validator(form, field): if len(field.data) > 0: invalid_chars = [c for c in field.data if c.isspace()] if invalid_chars: raise ValidationError(gettext('Passwords can not contain a space')) if len(field.data) < 8: raise ValidationError( gettext('password lenght must be at least 8 characters long'))
def login_validator(form, field): invalid_chars = [ c for c in field.data if c.isupper() or not c.isalnum() and c not in '._' ] if invalid_chars: raise ValidationError(gettext('Invalid characters found: %(char)s', char=', '.join(invalid_chars))) if len(field.data) < 5: raise ValidationError(gettext('login lenght must be at least 5 characters long'))
def create(): check_certificates() original_url = request.args.get('url') if original_url: bookmarklet_from = original_url else: bookmarklet_from = None original_application = None if original_url: applications = db.session.query(EmbedApplication).filter_by(url=original_url).all() if applications: original_application = applications[0] for app in applications: if len(app.translations) > len(original_application.translations): original_application = app if app.name and not original_application.name: original_application = app continue if app.description and not original_application.description: original_application = app continue if original_application is not None: form = ApplicationForm(obj=original_application) else: form = ApplicationForm() if not form.url.data and original_url: form.url.data = original_url if not form.name.data: result = get_url_metadata(original_url, timeout = 5) if result['name']: form.name.data = result['name'] if result['description'] and not form.description.data: form.description.data = result['description'] if form.url.data: form.url.data = form.url.data.strip() if form.validate_on_submit(): form_scale = _get_scale_value(form) application = EmbedApplication(url = form.url.data, name = form.name.data, owner = current_golab_user(), height=form.height.data, scale=form_scale, description=form.description.data, age_ranges_range = form.age_ranges_range.data) application.domains_text = form.domains_text.data db.session.add(application) try: db.session.commit() except Exception as e: traceback.print_exc() return render_template("embed/error.html", message = gettext("There was an error creating an application"), user = current_golab_user()), 500 else: kwargs = {} if bookmarklet_from: kwargs['url'] = bookmarklet_from return redirect(url_for('.edit', identifier=application.identifier, **kwargs)) return render_template("embed/create.html", form=form, header_message=gettext("Add a web"), user = current_golab_user(), bookmarklet_from=bookmarklet_from, create=True, edit=False)
def app_html(identifier): application = db.session.query(EmbedApplication).filter_by( identifier=identifier).first() if application is None: return render_template( "embed/error.html", user=current_golab_user(), message=gettext("Application '{identifier}' not found").format( identifier=identifier)), 404 apps_per_language = {} languages = ['en'] for translation in application.translations: apps_per_language[translation.language] = { 'url': translation.url, 'full_url': translation.full_url, } languages.append(translation.language) author = application.owner.display_name domain = urlparse.urlparse(application.url).netloc unsupported_url = db.session.query(HttpsUnsupportedUrl).filter_by( url=domain).first() # TODO: is this really useful? (unsupported_url) supports_https = application.url.startswith( 'https://') or application.uses_proxy requires_https = False if (request.args.get('requires_https') or '').lower() in ['true', '1']: requires_https = True if request.environ.get('old_wsgi.url_scheme') == 'https': requires_https = True print(requires_https, supports_https) if requires_https and not supports_https: return render_template("embed/popup.html", identifier=identifier, app=application, apps_per_language=apps_per_language, name=application.name, title=application.name) return render_template( "embed/app-embed.html", author=author, user=current_golab_user(), identifier=identifier, app=application, languages=languages, apps_per_language=apps_per_language, supports_https=supports_https, requires_https=requires_https, title=gettext("Application {name}").format(name=application.name))
def school_short_name_validator(form, field): if len(field.data) < 4 or len(field.data) > 15: raise ValidationError(gettext('Short name must be between 4 and 15 characters long')) else: invalid_chars = [ c for c in field.data if not c.isalnum() and c not in '.'] if invalid_chars: raise ValidationError(gettext('Invalid characters found: %(char)s', char=', '.join(invalid_chars)))
def password_validator(form, field): if len(field.data) > 0: invalid_chars = [ c for c in field.data if c.isspace() ] if invalid_chars: raise ValidationError(gettext('Passwords can not contain a space')) if len(field.data) < 8: raise ValidationError(gettext('password lenght must be at least 8 characters long'))
def verify_credentials(): if 'oauth_consumer_key' in request.form: consumer_key = request.form['oauth_consumer_key'] permission_to_lt_user = PermissionToLtUser.find(key = consumer_key) # TODO: check for nonce # TODO: check for old requests if permission_to_lt_user is None: response = Response(render_template('lti/errors.html', message = gettext("Invalid consumer key. Please check it again."))) # response.status_code = 412 return response secret = permission_to_lt_user.secret # The original dict is in unicode, which does not work with ToolProvider USE_UNICODE = False if USE_UNICODE: data_dict = request.form.to_dict() else: data_dict = {} for key, value in request.form.to_dict().iteritems(): data_dict[key.encode('utf8')] = value.encode('utf8') tool_provider = ToolProvider(consumer_key, secret, data_dict) try: return_value = tool_provider.valid_request(request) except: traceback.print_exc() response = Response(render_template('lti/errors.html', message = gettext("Invalid secret: could not validate request."))) # response.status_code = 403 return response else: if return_value == False: response = Response(render_template('lti/errors.html', message = gettext("Request checked and failed. Please check that the 'secret' is correct."))) # response.status_code = 403 return response session['author_identifier'] = request.form['user_id'] if 'lis_person_name_full' in request.form: session['user_fullname'] = request.form['lis_person_name_full'] if 'context_id' in request.form: session['group_id'] = request.form['context_id'] if 'context_title' in request.form: session['group_name'] = request.form['context_title'] if 'launch_presentation_locale' in request.form: session['launch_locale'] = request.form['launch_presentation_locale'] if 'launch_presentation_document_target' in request.form: session['launch_presentation_document_target'] = request.form['launch_presentation_document_target'] if 'launch_presentation_return_url' in request.form: session['launch_presentation_return_url'] = request.form['launch_presentation_return_url'] session['consumer'] = consumer_key session['last_request'] = time() return elif 'consumer' in session: if float(session['last_request']) - time() < 60 * 60 * 5: # Five Hours session['last_request'] = time() return else: response = Response(render_template('lti/errors.html', message = gettext("Session not initialized. Are you a LMS?"))) # response.status_code = 403 return response
def index(self): form = SpaceUrlForm() permissions = current_user.lt.lab_permissions lab_ids = dict([(permission.local_identifier, { 'name': permission.laboratory.name, 'checked': request.form.get('lab_%s' % permission.local_identifier, 'off') in ('checked', 'on') }) for permission in permissions]) request_space_name = False if form.validate_on_submit(): try: context_id = parse_space_url(form.url.data) except Exception as e: form.url.errors.append(e.message) else: existing_course = self.session.query(Course).filter_by( lt=current_user.lt, context_id=context_id).first() if existing_course: form.url.errors.append( gettext(u"Space already registered")) else: space_name = retrieve_space_name(context_id) # If space_name can not be retrieved (e.g., a closed or hidden space) if not space_name: # Try to get it from the form. space_name = request.form.get('space_name') # If it was possible, add the new space if space_name: course = create_new_space( context_id, space_name or gettext('Invalid name')) labs_to_grant = [ lab_id for lab_id in lab_ids if lab_ids[lab_id]['checked'] ] for lab_to_grant in labs_to_grant: permission = [ permission for permission in permissions if permission.local_identifier == lab_to_grant ][0] permission_to_course = PermissionToCourse( course=course, permission_to_lt=permission) db.session.add(permission_to_course) db.session.commit() return redirect( url_for('%s.index_view' % self.courses_panel_endpoint)) # But if it was not possible to add it, add a new field called space_name else: request_space_name = True return self.render("ple_admin/new_space.html", form=form, lab_ids=lab_ids, request_space_name=request_space_name)
def obtain_groups(): """ Obtains the groups that are available for translation, as an Ordered Dictionary. :return: Ordered dictionary with the name of the groups identified by each key. :rtype: OrderedDict """ groups = OrderedDict() groups["ALL"] = "ALL" groups["10-13"] = gettext("Preadolescence (age 10-13)") groups["14-18"] = gettext("Adolescence (age 14-18)") return groups
def login_validator(form, field): invalid_chars = [ c for c in field.data if c.isupper() or not c.isalnum() and c not in '._' ] if invalid_chars: raise ValidationError( gettext('Invalid characters found: %(char)s', char=', '.join(invalid_chars))) if len(field.data) < 5: raise ValidationError( gettext('login lenght must be at least 5 characters long'))
def school_short_name_validator(form, field): if len(field.data) < 4 or len(field.data) > 15: raise ValidationError( gettext('Short name must be between 4 and 15 characters long')) else: invalid_chars = [ c for c in field.data if not c.isalnum() and c not in '.' ] if invalid_chars: raise ValidationError( gettext('Invalid characters found: %(char)s', char=', '.join(invalid_chars)))
def app(identifier): application = db.session.query(EmbedApplication).filter_by( identifier=identifier).first() if application is None: return render_template( "embed/error.html", message=gettext("Application '{identifier}' not found").format( identifier=identifier), user=current_golab_user()), 404 return render_template( "embed/app.html", user=current_golab_user(), app=application, title=gettext("Application {name}").format(name=application.name))
def apps(): applications = db.session.query(EmbedApplication).order_by( EmbedApplication.last_update).all() return render_template("embed/apps.html", user=current_golab_user(), applications=applications, title=gettext("List of applications"))
def launch_lab(self): lab_id = request.args.get('id') lab = self.session.query(Laboratory).filter_by(id = lab_id).first() if lab is None: return "Laboratory id not found", 404 db_rlms = lab.rlms ManagerClass = get_manager_class(db_rlms.kind, db_rlms.version, db_rlms.id) remote_laboratory = ManagerClass(db_rlms.configuration) back_url = url_for('.display_lab', id = lab_id) try: response = remote_laboratory.reserve(lab.laboratory_id, current_user.login, "admin-panel", "{}", [], {}, { 'user_agent' : unicode(request.user_agent), 'from_ip' : remote_addr(), 'referer' : request.referrer, }, back_url = back_url, debug = True) load_url = response['load_url'] except Exception as e: flash(gettext("There was a problem testing this experiment. Error message: %s" % e)) return redirect(back_url) return redirect(load_url)
def get_json(): if request.json is not None: return request.json else: try: if request.data: data = request.data else: keys = request.form.keys() or [''] data = keys[0] return json.loads(data) except: print gettext("Invalid JSON found") print gettext(u"Suggested JSON: %(rdata)r", rdata=data) traceback.print_exc() return None
def launch_lab(self): lab_id = request.args.get('id') lab = self.session.query(Laboratory).filter_by(id=lab_id).first() if lab is None: return "Laboratory id not found", 404 db_rlms = lab.rlms ManagerClass = get_manager_class(db_rlms.kind, db_rlms.version, db_rlms.id) remote_laboratory = ManagerClass(db_rlms.configuration) back_url = url_for('.display_lab', id=lab_id) try: response = remote_laboratory.reserve( lab.laboratory_id, current_user.login, "admin-panel", "{}", [], {}, { 'user_agent': unicode(request.user_agent), 'from_ip': remote_addr(), 'referer': request.referrer, }, back_url=back_url, debug=True) load_url = response['load_url'] except Exception as e: flash( gettext( "There was a problem testing this experiment. Error message: %s" % e)) return redirect(back_url) return redirect(load_url)
def load_user(userid): if userid.startswith(u'labmanager_admin::'): login = userid.split(u'labmanager_admin::')[1] return LabManagerUser.find(login = login) if userid.startswith(u'lt_user::'): try: _, lt_name, login = userid.split('::') except ValueError: print gettext("Invalid format (expected lt_user::lt_name::login)") return None potential_users = [ user for user in LtUser.all(login = login) if user.lt.name == lt_name ] if len(potential_users) == 0: return None else: return potential_users[0] return None
def requires_lms_auth(): UNAUTHORIZED = Response( response=gettext("Could not verify your credentials for that URL"), status=401, headers={'WWW-Authenticate': 'Basic realm="Login Required"'}) auth = request.authorization if not auth: json_data = get_json() if json_data is None: return UNAUTHORIZED username = json_data.get('lms_username', '') password = json_data.get('lms_password', '') else: username = auth.username password = auth.password password = unicode(password) hash_password = hashlib.new(ALGORITHM, password.encode('utf8')).hexdigest() # TODO: check if there could be a conflict between two LTs with same key?? credential = db.session.query(BasicHttpCredentials).filter_by( lt_login=username, lt_password=hash_password).first() if credential is None: return UNAUTHORIZED g.lt = credential.lt.name
def scorm_formatter(v, c, laboratory, p): if current_user.lt.basic_http_authentications: for permission in laboratory.lab_permissions: if permission.lt == current_user.lt: local_id = permission.local_identifier return Markup('<a href="%s">Download</a>' % (url_for('.get_scorm', local_id = local_id))) return gettext('N/A')
def retrieve_courses(url, user, password): req = urllib2.Request(url, '') req.add_header('Content-type','application/json') password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() password_mgr.add_password(None, url, user, password) password_handler = urllib2.HTTPBasicAuthHandler(password_mgr) opener = urllib2.build_opener(password_handler) try: json_results= opener.open(req).read() except: traceback.print_exc() return gettext("Error opening provided URL") try: return json.loads(json_results) except: print gettext("Invalid JSON"), json_results return gettext("Invalid JSON")
def retrieve_courses(url, user, password): req = urllib2.Request(url, '') req.add_header('Content-type', 'application/json') password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() password_mgr.add_password(None, url, user, password) password_handler = urllib2.HTTPBasicAuthHandler(password_mgr) opener = urllib2.build_opener(password_handler) try: json_results = opener.open(req).read() except: traceback.print_exc() return gettext("Error opening provided URL") try: return json.loads(json_results) except: print gettext("Invalid JSON"), json_results return gettext("Invalid JSON")
def fake_list_courses(): # return """{"start":"2","number":3,"per-page":2,"courses":[{"id":"4","name":"example3"}]}""" auth = request.authorization if auth is None or auth.username not in ( 'test', 'labmanager') or auth.password not in ('test', 'password'): return Response(gettext('You have to login with proper credentials'), 401, {'WWW-Authenticate': 'Basic realm="Login Required"'}) q = request.args.get('q', '') start_str = request.args.get('start', '0') try: start = int(start_str) except: return gettext("Invalid start") fake_data = [] for pos in xrange(10000): if pos % 3 == 0: fake_data.append((str(pos), gettext("Fake electronics course %(coursepos)s", coursepos=pos))) elif pos % 3 == 1: fake_data.append((str(pos), gettext("Fake physics course %(coursepos)s", coursepos=pos))) else: fake_data.append((str(pos), gettext("Fake robotics course %(coursepos)s", coursepos=pos))) fake_return_data = [] for key, value in fake_data: if q in value: fake_return_data.append({ 'id': key, 'name': value, }) N = 10 view = { 'start': start, 'number': len(fake_return_data), 'per-page': N, 'courses': fake_return_data[start:start + N], } return json.dumps(view, indent=4)
def load_user(userid): if userid.startswith(u'labmanager_admin::'): login = userid.split(u'labmanager_admin::')[1] return LabManagerUser.find(login=login) if userid.startswith(u'lt_user::'): try: _, lt_name, login = userid.split('::') except ValueError: print gettext("Invalid format (expected lt_user::lt_name::login)") return None potential_users = [ user for user in LtUser.all(login=login) if user.lt.name == lt_name ] if len(potential_users) == 0: return None else: return potential_users[0] return None
def format_space_url(v, c, space, p): shindig_url = space.lt.shindig_credentials[0] assert shindig_url or True # Avoid pyflakes warnings # shindig_space_url = '%s/rest/spaces/%s' % (shindig_url, space.context_id) # contents = urllib2.urlopen(shindig_space_url).read() # return json.loads(contents)['urls'][0]['value'] return Markup( '<a target="_blank" href="https://graasp.epfl.ch/#item=space_%s">%s</a>' % (space.context_id, gettext('link')))
def list_widgets(self, local_identifier): laboratory = self.session.query(Laboratory).join(PermissionToLt).filter_by(lt = current_user.lt, local_identifier = local_identifier).first() if laboratory is None: return self.render("ple_admin/errors.html", message = gettext("Laboratory not found")) rlms_db = laboratory.rlms RLMS_CLASS = get_manager_class(rlms_db.kind, rlms_db.version) rlms = RLMS_CLASS(rlms_db.configuration) widgets = rlms.list_widgets(laboratory.laboratory_id) return self.render("ple_admin/list_widgets.html", widgets = widgets, institution_id = current_user.lt.name, lab_name = local_identifier)
def login_lms(): """Login screen for application""" DEFAULT_NEXT = url_for('lms_admin.index') next = request.args.get('next', DEFAULT_NEXT) print next lmss = [ lt for lt in LearningTool.all() if len(lt.shindig_credentials) == 0 ] if request.method == 'GET': return render_template('login_lms.html', next=next, lmss=lmss, action_url=url_for('login_lms')) if request.method == 'POST' and 'username' in request.form: username = request.form['username'] hashed = unicode( new_hash(ALGORITHM, request.form['password'].encode('utf8')).hexdigest()) lms_id = request.form['lms'] user = LtUser.exists(username, hashed, lms_id) if user is not None: if login_user(user): session['loggeduser'] = username session['last_request'] = time() session['usertype'] = 'lms' if next == DEFAULT_NEXT: if user.access_level == 'instructor': next = url_for('lms_instructor.index') return redirect(next) else: flash(gettext(u'Could not log in.')) return render_template('login_lms.html', next=next, lmss=lmss, action_url=url_for('login_lms')) else: flash(gettext(u'Invalid username.')) return render_template('login_lms.html', next=next, lmss=lmss, action_url=url_for('login_lms')) return gettext("Error in create_session")
def load_user(userid): if userid.startswith(u'labmanager_admin::'): login = userid.split(u'labmanager_admin::')[1] return LabManagerUser.find(login = login) if userid.startswith(u'lt_user::'): try: _, lt_name, login = userid.split('::') except ValueError: print gettext("Invalid format (expected lt_user::lt_name::login)") return None potential_users = [ user for user in LtUser.all(login = login) if user.lt.name == lt_name ] if len(potential_users) == 0: return None else: return potential_users[0] if userid.startswith(u'golab::'): email = userid.split('::', 1)[1] return db_session.query(GoLabOAuthUser).filter_by(email = email).first() return None
def go_lab_reservation_formatter(v, c, lab, p): if lab.go_lab_reservation: klass = 'btn-danger' msg = gettext('Deactivate') else: klass = 'btn-success' msg = gettext('Activate') return Markup("""<form method='POST' action='%(url)s' style="text-align: center"> <input type='hidden' name='activate' value='%(activate_value)s'/> <input type='hidden' name='lab_id' value='%(lab_id)s'/> <label> %(texto)s </label> <br> <input class='btn %(klass)s' type='submit' value="%(msg)s"></input> </form>""" % dict( url = url_for('.change_go_lab_reservation'), texto = gettext('Go-Lab Reservation'), activate_value = unicode(lab.go_lab_reservation).lower(), lab_id = lab.id, klass = klass, msg = msg ))
def load_user(userid): if userid.startswith(u'labmanager_admin::'): login = userid.split(u'labmanager_admin::')[1] return LabManagerUser.find(login=login) if userid.startswith(u'lt_user::'): try: _, lt_name, login = userid.split('::') except ValueError: print gettext("Invalid format (expected lt_user::lt_name::login)") return None potential_users = [ user for user in LtUser.all(login=login) if user.lt.name == lt_name ] if len(potential_users) == 0: return None else: return potential_users[0] if userid.startswith(u'golab::'): email = userid.split('::', 1)[1] return db_session.query(GoLabOAuthUser).filter_by(email=email).first() return None
def go_lab_reservation_formatter(v, c, lab, p): if lab.go_lab_reservation: klass = 'btn-danger' msg = gettext('Deactivate') else: klass = 'btn-success' msg = gettext('Activate') return Markup( """<form method='POST' action='%(url)s' style="text-align: center"> <input type='hidden' name='activate' value='%(activate_value)s'/> <input type='hidden' name='lab_id' value='%(lab_id)s'/> <label> %(texto)s </label> <br> <input class='btn %(klass)s' type='submit' value="%(msg)s"></input> </form>""" % dict(url=url_for('.change_go_lab_reservation'), texto=gettext('Go-Lab Reservation'), activate_value=unicode(lab.go_lab_reservation).lower(), lab_id=lab.id, klass=klass, msg=msg))
def check_json(): url = request.args.get('url') if not url: return jsonify(error=True, message=gettext("No URL provided"), url=url) if not url.startswith(('http://', 'https://')): return jsonify(error=True, message=gettext("URL doesn't start by http:// or https://"), url=url) if url == 'http://': return jsonify(error=False, url=url) sg_link = find_smartgateway_link(url, request.referrer) if sg_link: return jsonify(error=False, sg_link=sg_link, url=url) metadata = get_url_metadata(url, timeout = 5) if metadata['error_retrieving']: return jsonify(error=True, message=gettext("Error retrieving URL"), url=url) if metadata['code'] != 200: return jsonify(error=True, message=gettext("Error accessing to the URL"), url=url) if metadata['x_frame_options'] in ('deny', 'sameorigin') or metadata['x_frame_options'].startswith('allow'): return jsonify(error=True, message=gettext("This website does not support being loaded from a different site, so it is unavailable for Go-Lab"), url=url) if 'html' not in metadata['content_type']: if 'shockwave' in metadata['content_type'] or 'flash' in metadata['content_type']: return jsonify(error=False, url=url) return jsonify(error=True, message=gettext("URL is not HTML"), url=url) return jsonify(error=False, url=url, name = metadata['name'], description = metadata['description'])
def public_availability_formatter(v, c, lab, p): if lab.publicly_available: klass = 'btn-danger' msg = gettext('Make not publicly available') return Markup( """<form method='POST' action='%(url)s' style="text-align: center"> <input type='hidden' name='activate' value='%(activate_value)s'/> <input type='hidden' name='lab_id' value='%(lab_id)s'/> <label> %(texto)s </label> <input disabled type='text' name='public_identifier' value='%(public_identifier)s' style='width: 150px'/> <input class='btn %(klass)s' type='submit' value="%(msg)s"></input> </form>""" % dict( url=url_for('.change_public_availability'), activate_value=unicode(lab.publicly_available).lower(), lab_id=lab.id, texto=gettext('Public identifier:'), klass=klass, msg=msg, public_identifier=lab.public_identifier, )) else: klass = 'btn-success' msg = gettext('Make publicly available') return Markup( """<form method='POST' action='%(url)s' style="text-align: center"> <input type='hidden' name='activate' value='%(activate_value)s'/> <input type='hidden' name='lab_id' value='%(lab_id)s'/> <label> %(texto)s </label> <input type='text' name='public_identifier' value='%(public_identifier)s' style='width: 150px'/> <input class='btn %(klass)s' type='submit' value="%(msg)s"></input> </form>""" % dict( url=url_for('.change_public_availability'), activate_value=unicode(lab.publicly_available).lower(), lab_id=lab.id, texto=gettext('Public identifier:'), klass=klass, msg=msg, public_identifier=lab.public_identifier, ))
def launch_experiment(): consumer_key = session.get('consumer') if consumer_key is None: return gettext("consumer key not found") permission_to_lt_user = PermissionToLtUser.find(key = consumer_key) if permission_to_lt_user is None: return gettext("permission not found") p_to_lt = permission_to_lt_user.permission_to_lt courses_configurations = [] # No such concept in the LTI version request_payload = {} # This could be populated in the HTML. Pending. lt_configuration = p_to_lt.configuration db_laboratory = p_to_lt.laboratory db_rlms = db_laboratory.rlms author = session.get('author_identifier', '(not in session)') referer = request.referrer ManagerClass = get_manager_class(db_rlms.kind, db_rlms.version, db_rlms.id) remote_laboratory = ManagerClass(db_rlms.configuration) request_info = { 'user_agent' : unicode(request.user_agent), 'from_ip' : remote_addr(), 'referer' : referer, } for key in 'group_name', 'group_id', 'user_fullname': if key in session: request_info[key] = session[key] kwargs = {} if 'launch_locale' in session: kwargs['locale'] = session['launch_locale'].split('-')[0].split('_')[0] response = remote_laboratory.reserve(db_laboratory.laboratory_id, author, p_to_lt.lt.name, lt_configuration, courses_configurations, request_payload, request_info, **kwargs) load_url = response['load_url'] return redirect(load_url)
def index(self): form = SpaceUrlForm() permissions = current_user.lt.lab_permissions lab_ids = dict([ (permission.local_identifier, { 'name' : permission.laboratory.name, 'checked' : request.form.get('lab_%s' % permission.local_identifier, 'off') in ('checked', 'on') }) for permission in permissions ]) request_space_name = False if form.validate_on_submit(): try: context_id = parse_space_url(form.url.data) except Exception as e: form.url.errors.append(e.message) else: existing_course = self.session.query(Course).filter_by(lt = current_user.lt, context_id = context_id).first() if existing_course: form.url.errors.append(gettext(u"Space already registered")) else: space_name = retrieve_space_name(context_id) # If space_name can not be retrieved (e.g., a closed or hidden space) if not space_name: # Try to get it from the form. space_name = request.form.get('space_name') # If it was possible, add the new space if space_name: course = create_new_space(context_id, space_name or gettext('Invalid name')) labs_to_grant = [ lab_id for lab_id in lab_ids if lab_ids[lab_id]['checked'] ] for lab_to_grant in labs_to_grant: permission = [ permission for permission in permissions if permission.local_identifier == lab_to_grant ][0] permission_to_course = PermissionToCourse(course = course, permission_to_lt = permission) db.session.add(permission_to_course) db.session.commit() return redirect(url_for('%s.index_view' % self.courses_panel_endpoint)) # But if it was not possible to add it, add a new field called space_name else: request_space_name = True return self.render("ple_admin/new_space.html", form = form, lab_ids = lab_ids, request_space_name = request_space_name)
def parse_space_url(url): """ Given a Graasp URL, retrieve the space identifier (a number) """ # This is done in a different way if the space url ends with a number (the url contains space_) or if the url ends with a text (the url contains url=) if 'space_' in url: try: context_id = int(url.split('space_')[1]) except: raise Exception(gettext("Invalid format. Expected space_NUMBER")) else: return context_id elif 'url=' in url: try: space_name = url.split('url=')[1] json_file = 'http://graasp.epfl.ch/item3a/' + space_name + '.json' json_response = urllib2.urlopen(json_file) contents=json.loads(json_response.read()) context_id=contents['id'] return context_id except: raise Exception(gettext("Invalid format. Expected a valid Graasp space URL")) raise Exception(gettext("Invalid format. Expected http://graasp.epfl.ch/#item=space_SOMETHING"))
def public_availability_formatter(v, c, lab, p): if lab.publicly_available: klass = 'btn-danger' msg = gettext('Make not publicly available') return Markup("""<form method='POST' action='%(url)s' style="text-align: center"> <input type='hidden' name='activate' value='%(activate_value)s'/> <input type='hidden' name='lab_id' value='%(lab_id)s'/> <label> %(texto)s </label> <input disabled type='text' name='public_identifier' value='%(public_identifier)s' style='width: 150px'/> <input class='btn %(klass)s' type='submit' value="%(msg)s"></input> </form>""" % dict( url = url_for('.change_public_availability'), activate_value = unicode(lab.publicly_available).lower(), lab_id = lab.id, texto = gettext('Public identifier:'), klass = klass, msg = msg, public_identifier = lab.public_identifier, )) else: klass = 'btn-success' msg = gettext('Make publicly available') return Markup("""<form method='POST' action='%(url)s' style="text-align: center"> <input type='hidden' name='activate' value='%(activate_value)s'/> <input type='hidden' name='lab_id' value='%(lab_id)s'/> <label> %(texto)s </label> <input type='text' name='public_identifier' value='%(public_identifier)s' style='width: 150px'/> <input class='btn %(klass)s' type='submit' value="%(msg)s"></input> </form>""" % dict( url = url_for('.change_public_availability'), activate_value = unicode(lab.publicly_available).lower(), lab_id = lab.id, texto = gettext('Public identifier:'), klass = klass, msg = msg, public_identifier = lab.public_identifier, ))
def fake_list_courses(): # return """{"start":"2","number":3,"per-page":2,"courses":[{"id":"4","name":"example3"}]}""" auth = request.authorization if auth is None or auth.username not in ('test','labmanager') or auth.password not in ('test','password'): return Response(gettext('You have to login with proper credentials'), 401, {'WWW-Authenticate': 'Basic realm="Login Required"'}) q = request.args.get('q','') start_str = request.args.get('start','0') try: start = int(start_str) except: return gettext("Invalid start") fake_data = [] for pos in xrange(10000): if pos % 3 == 0: fake_data.append((str(pos), gettext("Fake electronics course %(coursepos)s", coursepos=pos))) elif pos % 3 == 1: fake_data.append((str(pos), gettext("Fake physics course %(coursepos)s", coursepos=pos))) else: fake_data.append((str(pos), gettext("Fake robotics course %(coursepos)s", coursepos=pos))) fake_return_data = [] for key, value in fake_data: if q in value: fake_return_data.append({ 'id' : key, 'name' : value, }) N = 10 view = { 'start' : start, 'number' : len(fake_return_data), 'per-page' : N, 'courses' : fake_return_data[start:start+N], } return json.dumps(view, indent = 4)
def change_accessibility(self): lab_id = int(request.form['lab_id']) activate = request.form['activate'] == 'true' lab = self.session.query(Laboratory).filter_by(id = lab_id).first() if lab is not None: if activate: lab.available = not activate lab.default_local_identifier = u"" else: local_id = request.form['default_local_identifier'] local_id = local_id.lstrip(' ') local_id = local_id.strip(' ') if not activate and len(local_id) == 0: flash(gettext("Invalid local identifier (empty)")) return redirect(url_for('.index_view')) existing_labs = self.session.query(Laboratory).filter_by(default_local_identifier=local_id).all() if len(existing_labs) > 0 and lab not in existing_labs: flash(gettext(u"Local identifier '%(localidentifier)s' already exists", localidentifier=local_id)) return redirect(url_for('.index_view')) lab.available = not activate lab.default_local_identifier = local_id self.session.add(lab) self.session.commit() return redirect(url_for('.index_view'))
def change_public_availability(self): lab_id = int(request.form['lab_id']) activate = request.form['activate'] == "true" lab = self.session.query(Laboratory).filter_by(id = lab_id).first() if lab is not None: if activate: lab.publicly_available = not activate lab.public_identifier = u"" else: public_id = request.form['public_identifier'] public_id = public_id.lstrip(' ') public_id = public_id.strip(' ') if not activate and len(public_id) == 0: flash(gettext("Invalid public identifier (empty)")) return redirect(url_for('.index_view')) existing_labs = self.session.query(Laboratory).filter_by(public_identifier=public_id).all() if len(existing_labs) > 0 and lab not in existing_labs: flash(gettext(u"Public identifier '%(publicidentifier)s' already exists", publicidentifier=public_id)) return redirect(url_for('.index_view')) lab.publicly_available = not activate lab.public_identifier = public_id self.session.add(lab) self.session.commit() return redirect(url_for('.index_view'))
def on_model_change(self, form, model): existing_permission = self.session.query(PermissionToLtUser).filter_by(lt_user = model.lt_user, permission_to_lt = model.permission_to_lt).first() if existing_permission: raise Exception(gettext("Existing permission on that user for that laboratory")) key = u'%s_%s_%s' % (current_user.lt, model.lt_user.login, model.permission_to_lt.local_identifier) key = key.lower().replace(' ','_') final_key = u'' for c in key: if c in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-': final_key += c else: final_key += '_' # uuid4 returns a random string (based on random functions, not in any characteristic of this computer or network) secret = uuid.uuid4().hex model.key = final_key model.secret = secret
def plugin_setup(self, rlms_id): rlms_obj = self.session.query(RLMS).filter_by(id = rlms_id).first() if not rlms_obj: return "RLMS not found", 404 if rlms_obj.kind != http_plugin.PLUGIN_NAME: return "RLMS is not HTTP", 400 ManagerClass = get_manager_class(rlms_obj.kind, rlms_obj.version, rlms_obj.id) rlms_instance = ManagerClass(rlms_obj.configuration) back_url = url_for('.edit_view', id = rlms_id, _external = True) try: setup_url = rlms_instance.setup(back_url = back_url) except Exception as e: flash(gettext("Couldn't load the setup URL! (this usually means that the plug-in is not correctly configured). Error message: %s" % e)) return redirect(back_url) else: return redirect(setup_url)