def milestone_report(token, repos, title, verbose=False, label=None): gh = Github(token) first_milestone = None issues = {} for repo in repos: r = gh.get_repo(repo) milestones = r.get_milestones() label_obj = "" if label: try: l = r.get_label(label) label_obj = [l] except UnknownObjectException: continue for milestone in milestones: if milestone.title == title: if not first_milestone: first_milestone = milestone github_issues = r.get_issues(milestone=milestone, state='all', labels=label_obj) if github_issues.totalCount > 0: issues[r] = github_issues env = Environment() loader = FileSystemLoader(dirname) tmpl = loader.load(env, 'milestone.md') context=dict(issues=issues, milestone=first_milestone, verbose=verbose) print tmpl.render(context)
class LabHandler(IPythonHandler): """Render the JupyterLab View.""" def initialize(self, lab_config): self.lab_config = lab_config self.file_loader = FileSystemLoader(lab_config.templates_dir) @web.authenticated @web.removeslash def get(self): config = self.lab_config settings_dir = config.app_settings_dir # Handle page config data. page_config = self.settings.setdefault('page_config_data', {}) terminals = self.settings.get('terminals_available', False) server_root = self.settings.get('server_root_dir', '') server_root = server_root.replace(os.sep, '/') page_config.setdefault('terminalsAvailable', terminals) page_config.setdefault('ignorePlugins', []) page_config.setdefault('serverRoot', server_root) mathjax_config = self.settings.get('mathjax_config', 'TeX-AMS_HTML-full,Safe') page_config.setdefault('mathjaxConfig', mathjax_config) page_config.setdefault('mathjaxUrl', self.mathjax_url) for name in config.trait_names(): page_config[_camelCase(name)] = getattr(config, name) # Load the current page config file if available. page_config_file = os.path.join(settings_dir, 'page_config.json') if os.path.exists(page_config_file): with open(page_config_file) as fid: try: page_config.update(json.load(fid)) except Exception as e: print(e) # Handle error when the assets are not available locally. local_index = os.path.join(config.static_dir, 'index.html') if config.static_dir and not os.path.exists(local_index): self.write(self.render_template( 'error.html', static_dir=config.static_dir )) return # Write the template with the config. self.write(self.render_template('index.html', page_config=page_config)) def get_template(self, name): return self.file_loader.load(self.settings['jinja2_env'], name) def render_template(self, name, **ns): try: return IPythonHandler.render_template(self, name, **ns) except TemplateError: return DEFAULT_TEMPLATE.generate( name=name, path=self.lab_config.templates_dir )
def write_html(data, outfile_name, **options): """ Produce HTML output. """ loader = FileSystemLoader(get_template_folder()) env = Environment() try: templ = loader.load(env, "html.jinja2") except TemplateNotFound: raise ViewNotImplementedError("The template '%s' was not found." % name) symbols = {'data': data} symbols.update(options) with open(outfile_name, "w") as fout: fout.write(templ.render(symbols))
def main(): env = Environment() loader = FileSystemLoader(project_path) template_opf = loader.load(env, opf_file) template_ncx = loader.load(env, ncx_file) #print template_opf.render(name='noisy') #ctx = Context(loadContext()); #d = {'unique_identifier':'test', 'dc_title':'title_test', 'dc_lang':'lang_test'} d = loadContext() ctx = Context(env, blocks=d, name=opf_file, parent=env.globals) template_opf.stream(**d).dump(project_path+'ekundelek_gen.opf') #unique_identifier='test', dc_title='title_test', dc_lang='lang_test') #jak dzia?a ** ? template_ncx.stream(**d).dump(project_path+'ekundelek_gen.ncx') #strim.dump(project_path+'ekundelek_gen.opf') print 'Gotowe!' pass
from jinja2 import Environment, FileSystemLoader # Load index template. my_template_path = '/srv/projects/intro_programming/intro_programming/notebooks/my_templates' my_template_base_path = '/srv/projects/intro_programming/intro_programming/notebooks' ipython_template_path = '/srv/projects/intro_programming/venv/lib/python3.4/site-packages/IPython/nbconvert/templates/html' my_loader = FileSystemLoader( [my_template_path, my_template_base_path, ipython_template_path]) env = Environment(loader=my_loader) index_template = my_loader.load(env, 'index.tpl') # Render template to file. notebooks_path = '/srv/projects/intro_programming/intro_programming/notebooks/' filepath = notebooks_path + 'index.html' with open(filepath, 'w') as f: f.write(index_template.render())
def get_template(self, name): loader = FileSystemLoader(HERE) return loader.load(self.settings['jinja2_env'], name)
def get_template(self, name): loader = FileSystemLoader(os.getcwd()) return loader.load(self.settings['jinja2_env'], name)
class ProxyApp(object): app = Klein() ns = "{http://www.yale.edu/tp/cas}" port = None logout_instant_skew = 5 ticket_name = 'ticket' service_name = 'service' renew_name = 'renew' pgturl_name = 'pgtUrl' reactor = reactor auth_info_resource = None auth_info_callback = None remoteUserHeader = 'Remote-User' logout_patterns = None logout_passthrough = False verbose = False proxy_client_endpoint_s = None cas_client_endpoint_s = None def __init__(self, proxied_url, cas_info, fqdn=None, authorities=None, plugins=None, is_https=True, excluded_resources=None, excluded_branches=None, remote_user_header=None, logout_patterns=None, logout_passthrough=False, template_dir=None, template_resource='/_templates', proxy_client_endpoint_s=None, cas_client_endpoint_s=None): self.proxy_client_endpoint_s = proxy_client_endpoint_s self.cas_client_endpoint_s = cas_client_endpoint_s self.logout_passthrough = logout_passthrough self.template_dir = template_dir if template_dir is not None: self.template_loader_ = FileSystemLoader(template_dir) self.template_env_ = Environment() self.templateStaticResource_ = self.create_template_static_resource() if template_resource is not None: if not template_resource.endswith('/'): template_resource = "{0}/".format(template_resource) if template_resource is not None and template_dir is not None: static_base = "{0}static/".format(template_resource) self.static = self.app.route(static_base, branch=True)(self.__class__.static) self.static_base = static_base self.template_resource = template_resource if logout_patterns is not None: self.logout_patterns = [parse_url_pattern(pattern) for pattern in logout_patterns] for pattern in self.logout_patterns: assert pattern is None or pattern.scheme == '', ( "Logout pattern '{0}' must be a relative URL.".format(pattern)) if remote_user_header is not None: self.remoteUserHeader = remote_user_header self.excluded_resources = excluded_resources self.excluded_branches = excluded_branches self.is_https = is_https if proxied_url.endswith('/'): proxied_url = proxied_url[:-1] self.proxied_url = proxied_url p = urlparse.urlparse(proxied_url) self.p = p self.proxied_scheme = p.scheme netloc = p.netloc self.proxied_netloc = netloc self.proxied_host = netloc.split(':')[0] self.proxied_path = p.path self.cas_info = cas_info cas_param_names = set([]) cas_param_names.add(self.ticket_name.lower()) cas_param_names.add(self.service_name.lower()) cas_param_names.add(self.renew_name.lower()) cas_param_names.add(self.pgturl_name.lower()) self.cas_param_names = cas_param_names if fqdn is None: fqdn = socket.getfqdn() self.fqdn = fqdn self.valid_sessions = {} self.logout_tickets = {} self._make_agents(authorities) # Sort/tag plugins if plugins is None: plugins = [] content_modifiers = [] info_acceptors = [] cas_redirect_handlers = [] interceptors = [] access_control = [] for plugin in plugins: if IResponseContentModifier.providedBy(plugin): content_modifiers.append(plugin) if IRProxyInfoAcceptor.providedBy(plugin): info_acceptors.append(plugin) if ICASRedirectHandler.providedBy(plugin): cas_redirect_handlers.append(plugin) if IResourceInterceptor.providedBy(plugin): interceptors.append(plugin) if IAccessControl.providedBy(plugin): access_control.append(plugin) self.info_acceptors = info_acceptors content_modifiers.sort(key=lambda x: x.mod_sequence) self.content_modifiers = content_modifiers cas_redirect_handlers.sort(key=lambda x: x.cas_redirect_sequence) self.cas_redirect_handlers = cas_redirect_handlers interceptors.sort(key=lambda x: x.interceptor_sequence) self.interceptors = interceptors access_control.sort(key=lambda x: x.ac_sequence) self.access_control = access_control # Create static resources. static_resources = {} for plugin in plugins: if IStaticResourceProvider.providedBy(plugin): if plugin.static_resource_base in static_resources: if static_resources[plugin.static_resource_base] != plugin.static_resource_dir: raise Exception("Static resource conflict for '{0}': '{1}' != '{2}'".format( plugin.static_resource_base, static_resources[plugin.static_resource_base], plugin.static_resource_dir)) else: static_resources[plugin.static_resource_base] = plugin.static_resource_dir self.static_handlers = [] for n, (resource_base, resource_dir) in enumerate(static_resources.iteritems()): handler = lambda self, request: File(resource_dir) handler = self.app.route(resource_base, branch=True)(handler) self.static_handlers.append(handler) def log(self, msg, important=False): if important or self.verbose: if important: tag = "INFO" else: tag = "DEBUG" log.msg("[{0}] {1}".format(tag, msg)) def handle_port_set(self): fqdn = self.fqdn port = self.port proxied_scheme = self.proxied_scheme proxied_netloc = self.proxied_netloc proxied_path = self.proxied_path for plugin in self.info_acceptors: plugin.proxy_fqdn = fqdn plugin.proxy_port = port plugin.proxied_scheme = proxied_scheme plugin.proxied_netloc = proxied_netloc plugin.proxied_path = proxied_path plugin.handle_rproxy_info_set() plugin.expire_session = self._expired def _make_agents(self, auth_files): """ Configure the web clients that: * perform backchannel CAS ticket validation * proxy the target site """ self.connectionPool = HTTPConnectionPool(self.reactor) if auth_files is None or len(auth_files) == 0: agent = Agent(self.reactor, pool=self.connectionPool) else: extra_ca_certs = [] for ca_cert in auth_files: with open(ca_cert, "rb") as f: data = f.read() cert = crypto.load_certificate(crypto.FILETYPE_PEM, data) del data extra_ca_certs.append(cert) policy = CustomPolicyForHTTPS(extra_ca_certs) agent = Agent(self.reactor, contextFactory=policy, pool=self.connectionPool) if self.proxy_client_endpoint_s is not None: self.proxyConnectionPool = HTTPConnectionPool(self.reactor) self.proxy_agent = Agent.usingEndpointFactory( self.reactor, WebClientEndpointFactory(self.reactor, self.proxy_client_endpoint_s), pool=self.proxyConnectionPool) else: self.proxy_agent = agent if self.cas_client_endpoint_s is not None: self.casConnectionPool = HTTPConnectionPool(self.reactor) self.cas_agent = Agent.usingEndpointFactory( self.reactor, WebClientEndpointFactory(self.reactor, self.cas_client_endpoint_s), pool=self.casConnectionPool) else: self.cas_agent = agent def is_excluded(self, request): resource = request.path if resource in self.excluded_resources: return True for excluded in self.excluded_branches: if proxyutils.is_resource_or_child(excluded, resource): return True return False def mod_headers(self, h): keymap = {} for k,v in h.iteritems(): key = k.lower() if key in keymap: keymap[key].append(k) else: keymap[key] = [k] if 'host' in keymap: for k in keymap['host']: h[k] = [self.proxied_netloc] if 'origin' in keymap: for k in keymap['origin']: h[k] = [self.proxied_netloc] if 'content-length' in keymap: for k in keymap['content-length']: del h[k] if 'referer' in keymap: referer_handled = False keys = keymap['referer'] if len(keys) == 1: k = keys[0] values = h[k] if len(values) == 1: referer = values[0] new_referer = self.proxy_url_to_proxied_url(referer) if new_referer is not None: h[k] = [new_referer] self.log("Re-wrote Referer header: '%s' => '%s'" % (referer, new_referer)) referer_handled = True if not referer_handled: for k in keymap['referer']: del h[k] return h def _check_for_logout(self, request): data = request.content.read() samlp_ns = "{urn:oasis:names:tc:SAML:2.0:protocol}" try: root = etree.fromstring(data) except Exception as ex: root = None if (root is not None) and (root.tag == "%sLogoutRequest" % samlp_ns): instant = root.get('IssueInstant') if instant is not None: try: instant = parse_date(instant) except ValueError: self.log("Invalid issue_instant supplied: '{0}'.".format(instant), important=True) instant = None if instant is not None: utcnow = datetime.datetime.utcnow() seconds = abs((utcnow - instant.replace(tzinfo=None)).total_seconds()) if seconds <= self.logout_instant_skew: results = root.findall("%sSessionIndex" % samlp_ns) if len(results) == 1: result = results[0] ticket = result.text sess_uid = self.logout_tickets.get(ticket, None) if sess_uid is not None: self._expired(sess_uid) return True else: self.log( ("No matching session for logout request " "for ticket '{0}'.").format(ticket)) else: self.log( ("Issue instant was not within" " {0} seconds of actual time.").format( self.logout_instant_skew), important=True) else: self.log("Could not parse issue instant.", important=True) else: self.log("'IssueInstant' attribute missing from root.", important=True) elif root is None: self.log("Could not parse XML.", important=True) return False @app.route("/", branch=True) def proxy(self, request): for pattern in self.logout_patterns: if does_url_match_pattern(request.uri, pattern): sess = request.getSession() sess_uid = sess.uid self._expired(sess_uid) cas_logout = self.cas_info.get('logout_url', None) if cas_logout is not None: if self.logout_passthrough: d = self.reverse_proxy(request, protected=False) return request.redirect(cas_logout) else: return self.reverse_proxy(request, protected=False) if self.is_excluded(request): return self.reverse_proxy(request, protected=False) valid_sessions = self.valid_sessions sess = request.getSession() sess_uid = sess.uid if not sess_uid in valid_sessions: self.log( ("Session {0} not in valid sessions. " "Will authenticate with CAS.").format(sess_uid)) if request.method == 'POST': headers = request.requestHeaders if headers.hasHeader("Content-Type"): ct_list = headers.getRawHeaders("Content-Type") #log.msg("[DEBUG] ct_list: %s" % str(ct_list)) for ct in ct_list: if ct.find('text/xml') != -1 or ct.find('application/xml') != -1: if self._check_for_logout(request): return "" else: break # CAS Authentication # Does this request have a ticket? I.e. is it coming back from a successful # CAS authentication? args = request.args ticket_name = self.ticket_name if ticket_name in args: values = args[ticket_name] if len(values) == 1: ticket = values[0] d = self.validate_ticket(ticket, request) return d # If no ticket is present, redirect to CAS. d = self.redirect_to_cas_login(request) return d elif request.path == self.auth_info_resource: self.log("Providing authentication info.") return self.deliver_auth_info(request) else: d = self.reverse_proxy(request) return d def deliver_auth_info(self, request): valid_sessions = self.valid_sessions sess = request.getSession() sess_uid = sess.uid session_info = valid_sessions[sess_uid] username = session_info['username'] attributes = session_info['attributes'] doc = {'username': username, 'attributes': attributes} serialized = json.dumps(doc) request.responseHeaders.setRawHeaders('Content-Type', ['application/json']) return serialized def get_url(self, request): if self.is_https: scheme = 'https' default_port = 443 else: scheme = 'http' default_port = 80 fqdn = self.fqdn port = self.port if port is None: port = default_port if port == default_port: return urlparse.urljoin("%s://%s" % (scheme, fqdn), request.uri) else: return urlparse.urljoin("%s://%s:%d" % (scheme, fqdn, port), request.uri) def redirect_to_cas_login(self, request): """ Begin the CAS redirection process. """ service_url = self.get_url(request) d = None for plugin in self.cas_redirect_handlers: if d is None: d = defer.maybeDeferred(plugin.intercept_service_url, service_url, request) else: d.addCallback(plugin.intercept_service_url, request) if d is None: return self.complete_redirect_to_cas_login(service_url, request) else: d.addCallback(self.complete_redirect_to_cas_login, request) return d def complete_redirect_to_cas_login(self, service_url, request): """ Complete the CAS redirection process. Return a deferred that will redirect the user-agent to the CAS login. """ cas_info = self.cas_info login_url = cas_info['login_url'] p = urlparse.urlparse(login_url) params = {self.service_name: service_url} if p.query == '': param_str = urlencode(params) else: qs_map = urlparse.parse_qs(p.query) qs_map.update(params) param_str = urlencode(qs_map, doseq=True) p = urlparse.ParseResult(*tuple(p[:4] + (param_str,) + p[5:])) url = urlparse.urlunparse(p) self.log("Redirecting to CAS with URL '{0}'.".format(url)) d = request.redirect(url) return d def validate_ticket(self, ticket, request): service_name = self.service_name ticket_name = self.ticket_name this_url = self.get_url(request) p = urlparse.urlparse(this_url) qs_map = urlparse.parse_qs(p.query) if ticket_name in qs_map: del qs_map[ticket_name] param_str = urlencode(qs_map, doseq=True) p = urlparse.ParseResult(*tuple(p[:4] + (param_str,) + p[5:])) service_url = urlparse.urlunparse(p) params = { service_name: service_url, ticket_name: ticket,} param_str = urlencode(params, doseq=True) p = urlparse.urlparse(self.cas_info['service_validate_url']) p = urlparse.ParseResult(*tuple(p[:4] + (param_str,) + p[5:])) service_validate_url = urlparse.urlunparse(p) self.log( "Requesting service-validate URL => '{0}' ...".format( service_validate_url)) http_client = HTTPClient(self.cas_agent) d = http_client.get(service_validate_url) d.addCallback(treq.content) d.addCallback(self.parse_sv_results, service_url, ticket, request) return d def parse_sv_results(self, payload, service_url, ticket, request): self.log("Parsing /serviceValidate results ...") ns = self.ns try: root = etree.fromstring(payload) except (etree.XMLSyntaxError,) as ex: self.log(( "error='Error parsing XML payload.' " "service='{0}' ticket={1}'/n{2}" ).format(service_url, ticket, ex), important=True) return self.render_template_500(request) if root.tag != ('%sserviceResponse' % ns): self.log(( "error='Error parsing XML payload. No `serviceResponse`.' " "service='{0}' ticket={1}'" ).format(service_url, ticket), important=True) return self.render_template_403(request) results = root.findall("{0}authenticationSuccess".format(ns)) if len(results) != 1: self.log(( "error='Error parsing XML payload. No `authenticationSuccess`.' " "service='{0}' ticket={1}'" ).format(service_url, ticket), important=True) return self.render_template_403(request) success = results[0] results = success.findall("{0}user".format(ns)) if len(results) != 1: self.log(( "error='Error parsing XML payload. Not exactly 1 `user`.' " "service='{0}' ticket={1}'" ).format(service_url, ticket), important=True) return self.render_template_403(request) user = results[0] username = user.text attributes = success.findall("{0}attributes".format(ns)) attrib_map = {} for attrib_container in attributes: for elm in attrib_container.findall('./*'): tag_name = elm.tag[len(ns):] value = elm.text attrib_map.setdefault(tag_name, []).append(value) # Access control plugins access_control = self.access_control for ac_plugin in access_control: is_allowed, reason = ac_plugin.isAllowed(username, attrib_map) if not is_allowed: self.log(( "Access denied: user='******' ac_plugin='{ac_plugin}' " "reason={reason}, service='{service}' ticket='{ticket}'" ).format( username=username, ac_plugin=ac_plugin.tagname, service=service_url, ticket=ticket, reason=reason), important=True) return self.render_template_403(request, username=username, reason=reason) # Update session session valid_sessions = self.valid_sessions logout_tickets = self.logout_tickets sess = request.getSession() sess_uid = sess.uid if sess_uid not in valid_sessions: valid_sessions[sess_uid] = {} valid_sessions[sess_uid].update({ 'username': username, 'ticket': ticket, 'attributes': attrib_map}) if not ticket in logout_tickets: logout_tickets[ticket] = sess_uid auth_info_callback = self.auth_info_callback if auth_info_callback is not None: auth_info_callback(username, attrib_map) sess.notifyOnExpire(lambda: self._expired(sess_uid)) # Reverse proxy. return request.redirect(service_url) def _expired(self, uid): valid_sessions = self.valid_sessions if uid in valid_sessions: session_info = valid_sessions[uid] username = session_info['username'] ticket = session_info['ticket'] del valid_sessions[uid] auth_info_callback = self.auth_info_callback if auth_info_callback is not None: auth_info_callback(username, None) logout_tickets = self.logout_tickets if ticket in logout_tickets: del logout_tickets[ticket] self.log( ("label='Expired session.' session_id='{0}' " "username='******'").format(uid, username)) def reverse_proxy(self, request, protected=True): if protected: sess = request.getSession() valid_sessions = self.valid_sessions sess_uid = sess.uid username = valid_sessions[sess_uid]['username'] # Normal reverse proxying. kwds = {} cookiejar = {} kwds['allow_redirects'] = False kwds['cookies'] = cookiejar req_headers = self.mod_headers(dict(request.requestHeaders.getAllRawHeaders())) kwds['headers'] = req_headers if protected: kwds['headers'][self.remoteUserHeader] = [username] if request.method in ('PUT', 'POST'): kwds['data'] = request.content.read() url = self.proxied_url + request.uri # Determine if a plugin wants to intercept this URL. interceptors = self.interceptors for interceptor in interceptors: if interceptor.should_resource_be_intercepted(url, request.method, req_headers, request): return interceptor.handle_resource(url, request.method, req_headers, request) # Check if this is a request for a websocket. d = self.checkForWebsocketUpgrade(request) if d is not None: return d # Typical reverse proxying. self.log("Proxying URL => {0}".format(url)) http_client = HTTPClient(self.proxy_agent) d = http_client.request(request.method, url, **kwds) def process_response(response, request): req_resp_headers = request.responseHeaders resp_code = response.code resp_headers = response.headers resp_header_map = dict(resp_headers.getAllRawHeaders()) # Rewrite Location headers for redirects as required. if resp_code in (301, 302, 303, 307, 308) and "Location" in resp_header_map: values = resp_header_map["Location"] if len(values) == 1: location = values[0] if request.isSecure(): proxy_scheme = 'https' else: proxy_scheme = 'http' new_location = self.proxied_url_to_proxy_url(proxy_scheme, location) if new_location is not None: resp_header_map['Location'] = [new_location] request.setResponseCode(response.code, message=response.phrase) for k,v in resp_header_map.iteritems(): if k == 'Set-Cookie': v = self.mod_cookies(v) req_resp_headers.setRawHeaders(k, v) return response def mod_content(body, request): """ Modify response content before returning it to the user agent. """ d = None for content_modifier in self.content_modifiers: if d is None: d = content_modifier.transform_content(body, request) else: d.addCallback(content_modifier.transform_content, request) if d is None: return body else: return d d.addCallback(process_response, request) d.addCallback(treq.content) d.addCallback(mod_content, request) return d def checkForWebsocketUpgrade(self, request): def _extract(name): raw_value = request.getHeader(name) if raw_value is None: return set([]) else: return set(raw_value.split(', ')) upgrade = _extract("Upgrade") connection = _extract("Connection") if 'websocket' in upgrade and 'Upgrade' in connection: uri = request.uri proxy_fqdn = self.fqdn proxy_port = self.port proxied_scheme = self.proxied_scheme proxied_netloc = self.proxied_netloc proxied_path = self.proxied_path if self.is_https: scheme = 'wss' else: scheme = 'ws' netloc = "{0}:{1}".format(proxy_fqdn, proxy_port) proxy_url = "{0}://{1}{2}".format(scheme, netloc, request.uri) if proxied_scheme == 'https': proxied_scheme = 'wss' else: proxied_scheme = 'ws' proxied_url = proxyutils.proxy_url_to_proxied_url( proxied_scheme, proxy_fqdn, proxy_port, proxied_netloc, proxied_path, proxy_url, ) origin = proxied_url kind = "tcp" if proxied_scheme == 'wss': kind = 'ssl' parts = proxied_netloc.split(":", 1) proxied_host = parts[0] if len(parts) == 2: proxied_port = int(parts[1]) elif proxied_scheme == 'wss': proxied_port = 443 else: proxied_port = 80 extra = "" #TODO: SSL options. proxied_endpoint_str = "{0}:host={1}:port={2}{3}".format( kind, proxied_host, proxied_port, extra ) if proxied_url is not None: resource = makeWebsocketProxyResource( proxy_url, proxied_endpoint_str, proxied_url, request, reactor=self.reactor, origin=origin, verbose=self.verbose) return resource return None def mod_cookies(self, value_list): proxied_path = self.proxied_path proxied_path_size = len(proxied_path) results = [] for cookie_value in value_list: c = Cookie.SimpleCookie() c.load(cookie_value) for k in c.keys(): m = c[k] if m.has_key('path'): m_path = m['path'] if self.is_proxy_path_or_child(m_path): m_path = m_path[proxied_path_size:] m['path'] = m_path results.append(c.output(header='')[1:]) return results def is_proxy_path_or_child(self, path): return proxyutils.is_proxy_path_or_child(self.proxied_path, path) def proxied_url_to_proxy_url(self, proxy_scheme, target_url): return proxyutils.proxied_url_to_proxy_url( proxy_scheme, self.fqdn, self.port, self.proxied_netloc, self.proxied_path, target_url) def proxy_url_to_proxied_url(self, target_url): return proxyutils.proxy_url_to_proxied_url( self.proxied_scheme, self.fqdn, self.port, self.proxied_netloc, self.proxied_path, target_url) def get_template_static_base(self): if self.template_resource is None: return None else: return '{0}static/'.format(self.template_resource) def render_template_403(self, request, **kwargs): template_dir = self.template_dir if template_dir is None: request.setResponseCode(403) return "" else: return self.render_template('error/403.jinja2', request=request, **kwargs) def render_template_500(self, request, **kwargs): template_dir = self.template_dir if template_dir is None: request.setResponseCode(500) return "" else: return self.render_template('error/500.jinja2', request=request, **kwargs) def render_template(self, template_name, **kwargs): template_dir = self.template_dir try: template = self.template_loader_.load(self.template_env_, template_name) except TemplateNotFound: raise Exception("The template '{0}' was not found.".format(template_name)) return template.render(static_base=self.static_base, **kwargs).encode('utf-8') def create_template_static_resource(self): static_path = os.path.join(self.template_dir, 'static') static = File(static_path) return static def static(self, request): return self.templateStaticResource_ @app.handle_errors(Exception) def handle_uncaught_errors(self, request, failure): self.log("Uncaught exception: {0}".format(failure), important=True) return self.render_template_500(request=request, failure=failure)
class LabHandler(JupyterHandler): """Render the JupyterLab View.""" def initialize(self, lab_config): self.lab_config = lab_config self.file_loader = FileSystemLoader(lab_config.templates_dir) @web.authenticated @web.removeslash def get(self): self.application.store_id = getattr(self.application, 'store_id', 0) config = self.lab_config settings_dir = config.app_settings_dir # Handle page config data. page_config = self.settings.setdefault('page_config_data', {}) terminals = self.settings.get('terminals_available', False) server_root = self.settings.get('server_root_dir', '') server_root = server_root.replace(os.sep, '/') base_url = self.settings.get('base_url') page_config.setdefault('terminalsAvailable', terminals) page_config.setdefault('ignorePlugins', []) page_config.setdefault('serverRoot', server_root) page_config['store_id'] = self.application.store_id self.application.store_id += 1 mathjax_config = self.settings.get('mathjax_config', 'TeX-AMS_HTML-full,Safe') page_config.setdefault('mathjaxConfig', mathjax_config) page_config.setdefault('fullMathjaxUrl', self.mathjax_url) # Put all our config in page_config for name in config.trait_names(): page_config[_camelCase(name)] = getattr(config, name) # Add full versions of all the urls for name in config.trait_names(): if not name.endswith('_url'): continue full_name = _camelCase('full_' + name) full_url = ujoin(base_url, getattr(config, name)) page_config[full_name] = full_url # Load the current page config file if available. page_config_file = os.path.join(settings_dir, 'page_config.json') if os.path.exists(page_config_file): with open(page_config_file) as fid: try: page_config.update(json.load(fid)) except Exception as e: print(e) # Write the template with the config. self.write(self.render_template('index.html', page_config=page_config)) def get_template(self, name): return self.file_loader.load(self.settings['jinja2_env'], name) def render_template(self, name, **ns): try: return JupyterHandler.render_template(self, name, **ns) except TemplateError: return DEFAULT_TEMPLATE.generate( name=name, path=self.lab_config.templates_dir)
class Application(ErrorResponses): middlewares = [CSRF()] def __init__(self, settings=None): self.settings = settings self.subs = list() self.app = self self.loader = FileSystemLoader(settings.TEMPLATES_PATH) def register(self, sub_class, path, *args, **kwargs): log.debug('registred %s' % sub_class) sub = sub_class(self, self, path, *args, **kwargs) self.subs.append(sub) return sub def full_path(self, current): return '' def _match_path(self, match, path, subs): match = dict() for sub in subs: submatch = sub.path.match(path) if submatch: # it is a good path matched = submatch.groupdict() if matched: matched.update(match) else: matched = match subpath = path[submatch.end():] if subpath: # try subs from this sub o = self._match_path(matched, subpath, sub.subs) if o[0]: # a sub of this sub is a match return it return o else: # if it matched but is not a subsub then it's the one # that match (and to repeat it: it's not a sub of sub!) return matched, sub # else continue # None matched return None, None def __call__(self, environ, start_response): request = Request(environ) for sub in self.subs: log.debug('try to match %s' % sub) # first match the domain if any try to match the path path_match, sub = self._match_path(dict(), request.path, [sub]) if not sub: continue # found the good sub request.path_match = path_match for middleware in self.middlewares: maybe_response = middleware.process_request_before_view(self, request) if isinstance(maybe_response, Response): return maybe_response(environ, start_response) try: response = sub(request) except Exception: # XXX: improve this print_exc() response = self.internal_server_error(request) for middleware in self.middlewares: maybe_response = middleware.process_response_before_answer(self, request, response) if isinstance(maybe_response, Response): return maybe_response(environ, start_response) return response(environ, start_response) else: for middleware in self.middlewares: maybe_response = middleware.process_response_before_answer(self, request, response) if isinstance(maybe_response, Response): return maybe_response(environ, start_response) return response(environ, start_response) response = self.not_found(request) for middleware in self.middlewares: maybe_response = middleware.process_response_before_answer(self, request, response) if isinstance(maybe_response, Response): return maybe_response(environ, start_response) return response(environ, start_response) def render(self, request, path, **context): response = Response(status=200) template = self.loader.load(Environment(), path) context['settings'] = self.settings context['request'] = request context['app'] = self.app response.text = template.render(**context) return response def redirect(self, url): return Response(status=302, location=url)
class ProxyApp(object): app = Klein() ns = "{http://www.yale.edu/tp/cas}" port = None logout_instant_skew = 5 ticket_name = 'ticket' service_name = 'service' renew_name = 'renew' pgturl_name = 'pgtUrl' reactor = reactor auth_info_resource = None auth_info_callback = None remoteUserHeader = 'Remote-User' logout_patterns = None logout_passthrough = False verbose = False proxy_client_endpoint_s = None cas_client_endpoint_s = None def __init__(self, proxied_url, cas_info, fqdn=None, authorities=None, plugins=None, is_https=True, excluded_resources=None, excluded_branches=None, remote_user_header=None, logout_patterns=None, logout_passthrough=False, template_dir=None, template_resource='/_templates', proxy_client_endpoint_s=None, cas_client_endpoint_s=None): self.proxy_client_endpoint_s = proxy_client_endpoint_s self.cas_client_endpoint_s = cas_client_endpoint_s self.logout_passthrough = logout_passthrough self.template_dir = template_dir if template_dir is not None: self.template_loader_ = FileSystemLoader(template_dir) self.template_env_ = Environment() self.templateStaticResource_ = self.create_template_static_resource( ) if template_resource is not None: if not template_resource.endswith('/'): template_resource = "{0}/".format(template_resource) if template_resource is not None and template_dir is not None: static_base = "{0}static/".format(template_resource) self.static = self.app.route(static_base, branch=True)(self.__class__.static) self.static_base = static_base self.template_resource = template_resource if logout_patterns is not None: self.logout_patterns = [ parse_url_pattern(pattern) for pattern in logout_patterns ] for pattern in self.logout_patterns: assert pattern is None or pattern.scheme == '', ( "Logout pattern '{0}' must be a relative URL.".format(pattern)) if remote_user_header is not None: self.remoteUserHeader = remote_user_header self.excluded_resources = excluded_resources self.excluded_branches = excluded_branches self.is_https = is_https if proxied_url.endswith('/'): proxied_url = proxied_url[:-1] self.proxied_url = proxied_url p = urlparse.urlparse(proxied_url) self.p = p self.proxied_scheme = p.scheme netloc = p.netloc self.proxied_netloc = netloc self.proxied_host = netloc.split(':')[0] self.proxied_path = p.path self.cas_info = cas_info cas_param_names = set([]) cas_param_names.add(self.ticket_name.lower()) cas_param_names.add(self.service_name.lower()) cas_param_names.add(self.renew_name.lower()) cas_param_names.add(self.pgturl_name.lower()) self.cas_param_names = cas_param_names if fqdn is None: fqdn = socket.getfqdn() self.fqdn = fqdn self.valid_sessions = {} self.logout_tickets = {} self._make_agents(authorities) # Sort/tag plugins if plugins is None: plugins = [] content_modifiers = [] info_acceptors = [] cas_redirect_handlers = [] interceptors = [] access_control = [] for plugin in plugins: if IResponseContentModifier.providedBy(plugin): content_modifiers.append(plugin) if IRProxyInfoAcceptor.providedBy(plugin): info_acceptors.append(plugin) if ICASRedirectHandler.providedBy(plugin): cas_redirect_handlers.append(plugin) if IResourceInterceptor.providedBy(plugin): interceptors.append(plugin) if IAccessControl.providedBy(plugin): access_control.append(plugin) self.info_acceptors = info_acceptors content_modifiers.sort(key=lambda x: x.mod_sequence) self.content_modifiers = content_modifiers cas_redirect_handlers.sort(key=lambda x: x.cas_redirect_sequence) self.cas_redirect_handlers = cas_redirect_handlers interceptors.sort(key=lambda x: x.interceptor_sequence) self.interceptors = interceptors access_control.sort(key=lambda x: x.ac_sequence) self.access_control = access_control # Create static resources. static_resources = {} for plugin in plugins: if IStaticResourceProvider.providedBy(plugin): if plugin.static_resource_base in static_resources: if static_resources[ plugin. static_resource_base] != plugin.static_resource_dir: raise Exception( "Static resource conflict for '{0}': '{1}' != '{2}'" .format( plugin.static_resource_base, static_resources[plugin.static_resource_base], plugin.static_resource_dir)) else: static_resources[ plugin. static_resource_base] = plugin.static_resource_dir self.static_handlers = [] for n, (resource_base, resource_dir) in enumerate(static_resources.iteritems()): handler = lambda self, request: File(resource_dir) handler = self.app.route(resource_base, branch=True)(handler) self.static_handlers.append(handler) def log(self, msg, important=False): if important or self.verbose: if important: tag = "INFO" else: tag = "DEBUG" log.msg("[{0}] {1}".format(tag, msg)) def handle_port_set(self): fqdn = self.fqdn port = self.port proxied_scheme = self.proxied_scheme proxied_netloc = self.proxied_netloc proxied_path = self.proxied_path for plugin in self.info_acceptors: plugin.proxy_fqdn = fqdn plugin.proxy_port = port plugin.proxied_scheme = proxied_scheme plugin.proxied_netloc = proxied_netloc plugin.proxied_path = proxied_path plugin.handle_rproxy_info_set() plugin.expire_session = self._expired def _make_agents(self, auth_files): """ Configure the web clients that: * perform backchannel CAS ticket validation * proxy the target site """ self.connectionPool = HTTPConnectionPool(self.reactor) if auth_files is None or len(auth_files) == 0: agent = Agent(self.reactor, pool=self.connectionPool) else: extra_ca_certs = [] for ca_cert in auth_files: with open(ca_cert, "rb") as f: data = f.read() cert = crypto.load_certificate(crypto.FILETYPE_PEM, data) del data extra_ca_certs.append(cert) policy = CustomPolicyForHTTPS(extra_ca_certs) agent = Agent(self.reactor, contextFactory=policy, pool=self.connectionPool) if self.proxy_client_endpoint_s is not None: self.proxyConnectionPool = HTTPConnectionPool(self.reactor) self.proxy_agent = Agent.usingEndpointFactory( self.reactor, WebClientEndpointFactory(self.reactor, self.proxy_client_endpoint_s), pool=self.proxyConnectionPool) else: self.proxy_agent = agent if self.cas_client_endpoint_s is not None: self.casConnectionPool = HTTPConnectionPool(self.reactor) self.cas_agent = Agent.usingEndpointFactory( self.reactor, WebClientEndpointFactory(self.reactor, self.cas_client_endpoint_s), pool=self.casConnectionPool) else: self.cas_agent = agent def is_excluded(self, request): resource = request.path if resource in self.excluded_resources: return True for excluded in self.excluded_branches: if proxyutils.is_resource_or_child(excluded, resource): return True return False def mod_headers(self, h): keymap = {} for k, v in h.iteritems(): key = k.lower() if key in keymap: keymap[key].append(k) else: keymap[key] = [k] if 'host' in keymap: for k in keymap['host']: h[k] = [self.proxied_netloc] if 'origin' in keymap: for k in keymap['origin']: h[k] = [self.proxied_netloc] if 'content-length' in keymap: for k in keymap['content-length']: del h[k] if 'referer' in keymap: referer_handled = False keys = keymap['referer'] if len(keys) == 1: k = keys[0] values = h[k] if len(values) == 1: referer = values[0] new_referer = self.proxy_url_to_proxied_url(referer) if new_referer is not None: h[k] = [new_referer] self.log("Re-wrote Referer header: '%s' => '%s'" % (referer, new_referer)) referer_handled = True if not referer_handled: for k in keymap['referer']: del h[k] return h def _check_for_logout(self, request): data = request.content.read() samlp_ns = "{urn:oasis:names:tc:SAML:2.0:protocol}" try: root = etree.fromstring(data) except Exception as ex: root = None if (root is not None) and (root.tag == "%sLogoutRequest" % samlp_ns): instant = root.get('IssueInstant') if instant is not None: try: instant = parse_date(instant) except ValueError: self.log("Invalid issue_instant supplied: '{0}'.".format( instant), important=True) instant = None if instant is not None: utcnow = datetime.datetime.utcnow() seconds = abs( (utcnow - instant.replace(tzinfo=None)).total_seconds()) if seconds <= self.logout_instant_skew: results = root.findall("%sSessionIndex" % samlp_ns) if len(results) == 1: result = results[0] ticket = result.text sess_uid = self.logout_tickets.get(ticket, None) if sess_uid is not None: self._expired(sess_uid) return True else: self.log( ("No matching session for logout request " "for ticket '{0}'.").format(ticket)) else: self.log(("Issue instant was not within" " {0} seconds of actual time.").format( self.logout_instant_skew), important=True) else: self.log("Could not parse issue instant.", important=True) else: self.log("'IssueInstant' attribute missing from root.", important=True) elif root is None: self.log("Could not parse XML.", important=True) return False @app.route("/", branch=True) def proxy(self, request): for pattern in self.logout_patterns: if does_url_match_pattern(request.uri, pattern): sess = request.getSession() sess_uid = sess.uid self._expired(sess_uid) cas_logout = self.cas_info.get('logout_url', None) if cas_logout is not None: if self.logout_passthrough: d = self.reverse_proxy(request, protected=False) return request.redirect(cas_logout) else: return self.reverse_proxy(request, protected=False) if self.is_excluded(request): return self.reverse_proxy(request, protected=False) valid_sessions = self.valid_sessions sess = request.getSession() sess_uid = sess.uid if not sess_uid in valid_sessions: self.log(("Session {0} not in valid sessions. " "Will authenticate with CAS.").format(sess_uid)) if request.method == 'POST': headers = request.requestHeaders if headers.hasHeader("Content-Type"): ct_list = headers.getRawHeaders("Content-Type") #log.msg("[DEBUG] ct_list: %s" % str(ct_list)) for ct in ct_list: if ct.find('text/xml') != -1 or ct.find( 'application/xml') != -1: if self._check_for_logout(request): return "" else: break # CAS Authentication # Does this request have a ticket? I.e. is it coming back from a successful # CAS authentication? args = request.args ticket_name = self.ticket_name if ticket_name in args: values = args[ticket_name] if len(values) == 1: ticket = values[0] d = self.validate_ticket(ticket, request) return d # If no ticket is present, redirect to CAS. d = self.redirect_to_cas_login(request) return d elif request.path == self.auth_info_resource: self.log("Providing authentication info.") return self.deliver_auth_info(request) else: d = self.reverse_proxy(request) return d def deliver_auth_info(self, request): valid_sessions = self.valid_sessions sess = request.getSession() sess_uid = sess.uid session_info = valid_sessions[sess_uid] username = session_info['username'] attributes = session_info['attributes'] doc = {'username': username, 'attributes': attributes} serialized = json.dumps(doc) request.responseHeaders.setRawHeaders('Content-Type', ['application/json']) return serialized def get_url(self, request): if self.is_https: scheme = 'https' default_port = 443 else: scheme = 'http' default_port = 80 fqdn = self.fqdn port = self.port if port is None: port = default_port if port == default_port: return urlparse.urljoin("%s://%s" % (scheme, fqdn), request.uri) else: return urlparse.urljoin("%s://%s:%d" % (scheme, fqdn, port), request.uri) def redirect_to_cas_login(self, request): """ Begin the CAS redirection process. """ service_url = self.get_url(request) d = None for plugin in self.cas_redirect_handlers: if d is None: d = defer.maybeDeferred(plugin.intercept_service_url, service_url, request) else: d.addCallback(plugin.intercept_service_url, request) if d is None: return self.complete_redirect_to_cas_login(service_url, request) else: d.addCallback(self.complete_redirect_to_cas_login, request) return d def complete_redirect_to_cas_login(self, service_url, request): """ Complete the CAS redirection process. Return a deferred that will redirect the user-agent to the CAS login. """ cas_info = self.cas_info login_url = cas_info['login_url'] p = urlparse.urlparse(login_url) params = {self.service_name: service_url} if p.query == '': param_str = urlencode(params) else: qs_map = urlparse.parse_qs(p.query) qs_map.update(params) param_str = urlencode(qs_map, doseq=True) p = urlparse.ParseResult(*tuple(p[:4] + (param_str, ) + p[5:])) url = urlparse.urlunparse(p) self.log("Redirecting to CAS with URL '{0}'.".format(url)) d = request.redirect(url) return d def validate_ticket(self, ticket, request): service_name = self.service_name ticket_name = self.ticket_name this_url = self.get_url(request) p = urlparse.urlparse(this_url) qs_map = urlparse.parse_qs(p.query) if ticket_name in qs_map: del qs_map[ticket_name] param_str = urlencode(qs_map, doseq=True) p = urlparse.ParseResult(*tuple(p[:4] + (param_str, ) + p[5:])) service_url = urlparse.urlunparse(p) params = { service_name: service_url, ticket_name: ticket, } param_str = urlencode(params, doseq=True) p = urlparse.urlparse(self.cas_info['service_validate_url']) p = urlparse.ParseResult(*tuple(p[:4] + (param_str, ) + p[5:])) service_validate_url = urlparse.urlunparse(p) self.log("Requesting service-validate URL => '{0}' ...".format( service_validate_url)) http_client = HTTPClient(self.cas_agent) d = http_client.get(service_validate_url) d.addCallback(treq.content) d.addCallback(self.parse_sv_results, service_url, ticket, request) return d def parse_sv_results(self, payload, service_url, ticket, request): self.log("Parsing /serviceValidate results ...") ns = self.ns try: root = etree.fromstring(payload) except (etree.XMLSyntaxError, ) as ex: self.log(("error='Error parsing XML payload.' " "service='{0}' ticket={1}'/n{2}").format( service_url, ticket, ex), important=True) return self.render_template_500(request) if root.tag != ('%sserviceResponse' % ns): self.log( ("error='Error parsing XML payload. No `serviceResponse`.' " "service='{0}' ticket={1}'").format(service_url, ticket), important=True) return self.render_template_403(request) results = root.findall("{0}authenticationSuccess".format(ns)) if len(results) != 1: self.log(( "error='Error parsing XML payload. No `authenticationSuccess`.' " "service='{0}' ticket={1}'").format(service_url, ticket), important=True) return self.render_template_403(request) success = results[0] results = success.findall("{0}user".format(ns)) if len(results) != 1: self.log( ("error='Error parsing XML payload. Not exactly 1 `user`.' " "service='{0}' ticket={1}'").format(service_url, ticket), important=True) return self.render_template_403(request) user = results[0] username = user.text attributes = success.findall("{0}attributes".format(ns)) attrib_map = {} for attrib_container in attributes: for elm in attrib_container.findall('./*'): tag_name = elm.tag[len(ns):] value = elm.text attrib_map.setdefault(tag_name, []).append(value) # Access control plugins access_control = self.access_control for ac_plugin in access_control: is_allowed, reason = ac_plugin.isAllowed(username, attrib_map) if not is_allowed: self.log(( "Access denied: user='******' ac_plugin='{ac_plugin}' " "reason={reason}, service='{service}' ticket='{ticket}'" ).format(username=username, ac_plugin=ac_plugin.tagname, service=service_url, ticket=ticket, reason=reason), important=True) return self.render_template_403(request, username=username, reason=reason) # Update session session valid_sessions = self.valid_sessions logout_tickets = self.logout_tickets sess = request.getSession() sess_uid = sess.uid if sess_uid not in valid_sessions: valid_sessions[sess_uid] = {} valid_sessions[sess_uid].update({ 'username': username, 'ticket': ticket, 'attributes': attrib_map }) if not ticket in logout_tickets: logout_tickets[ticket] = sess_uid auth_info_callback = self.auth_info_callback if auth_info_callback is not None: auth_info_callback(username, attrib_map) sess.notifyOnExpire(lambda: self._expired(sess_uid)) # Reverse proxy. return request.redirect(service_url) def _expired(self, uid): valid_sessions = self.valid_sessions if uid in valid_sessions: session_info = valid_sessions[uid] username = session_info['username'] ticket = session_info['ticket'] del valid_sessions[uid] auth_info_callback = self.auth_info_callback if auth_info_callback is not None: auth_info_callback(username, None) logout_tickets = self.logout_tickets if ticket in logout_tickets: del logout_tickets[ticket] self.log(("label='Expired session.' session_id='{0}' " "username='******'").format(uid, username)) def reverse_proxy(self, request, protected=True): if protected: sess = request.getSession() valid_sessions = self.valid_sessions sess_uid = sess.uid username = valid_sessions[sess_uid]['username'] # Normal reverse proxying. kwds = {} cookiejar = {} kwds['allow_redirects'] = False kwds['cookies'] = cookiejar req_headers = self.mod_headers( dict(request.requestHeaders.getAllRawHeaders())) kwds['headers'] = req_headers if protected: kwds['headers'][self.remoteUserHeader] = [username] if request.method in ('PUT', 'POST'): kwds['data'] = request.content.read() url = self.proxied_url + request.uri # Determine if a plugin wants to intercept this URL. interceptors = self.interceptors for interceptor in interceptors: if interceptor.should_resource_be_intercepted( url, request.method, req_headers, request): return interceptor.handle_resource(url, request.method, req_headers, request) # Check if this is a request for a websocket. d = self.checkForWebsocketUpgrade(request) if d is not None: return d # Typical reverse proxying. self.log("Proxying URL => {0}".format(url)) http_client = HTTPClient(self.proxy_agent) d = http_client.request(request.method, url, **kwds) def process_response(response, request): req_resp_headers = request.responseHeaders resp_code = response.code resp_headers = response.headers resp_header_map = dict(resp_headers.getAllRawHeaders()) # Rewrite Location headers for redirects as required. if resp_code in (301, 302, 303, 307, 308) and "Location" in resp_header_map: values = resp_header_map["Location"] if len(values) == 1: location = values[0] if request.isSecure(): proxy_scheme = 'https' else: proxy_scheme = 'http' new_location = self.proxied_url_to_proxy_url( proxy_scheme, location) if new_location is not None: resp_header_map['Location'] = [new_location] request.setResponseCode(response.code, message=response.phrase) for k, v in resp_header_map.iteritems(): if k == 'Set-Cookie': v = self.mod_cookies(v) req_resp_headers.setRawHeaders(k, v) return response def mod_content(body, request): """ Modify response content before returning it to the user agent. """ d = None for content_modifier in self.content_modifiers: if d is None: d = content_modifier.transform_content(body, request) else: d.addCallback(content_modifier.transform_content, request) if d is None: return body else: return d d.addCallback(process_response, request) d.addCallback(treq.content) d.addCallback(mod_content, request) return d def checkForWebsocketUpgrade(self, request): def _extract(name): raw_value = request.getHeader(name) if raw_value is None: return set([]) else: return set(raw_value.split(', ')) upgrade = _extract("Upgrade") connection = _extract("Connection") if 'websocket' in upgrade and 'Upgrade' in connection: uri = request.uri proxy_fqdn = self.fqdn proxy_port = self.port proxied_scheme = self.proxied_scheme proxied_netloc = self.proxied_netloc proxied_path = self.proxied_path if self.is_https: scheme = 'wss' else: scheme = 'ws' netloc = "{0}:{1}".format(proxy_fqdn, proxy_port) proxy_url = "{0}://{1}{2}".format(scheme, netloc, request.uri) if proxied_scheme == 'https': proxied_scheme = 'wss' else: proxied_scheme = 'ws' proxied_url = proxyutils.proxy_url_to_proxied_url( proxied_scheme, proxy_fqdn, proxy_port, proxied_netloc, proxied_path, proxy_url, ) origin = proxied_url kind = "tcp" if proxied_scheme == 'wss': kind = 'ssl' parts = proxied_netloc.split(":", 1) proxied_host = parts[0] if len(parts) == 2: proxied_port = int(parts[1]) elif proxied_scheme == 'wss': proxied_port = 443 else: proxied_port = 80 extra = "" #TODO: SSL options. proxied_endpoint_str = "{0}:host={1}:port={2}{3}".format( kind, proxied_host, proxied_port, extra) if proxied_url is not None: resource = makeWebsocketProxyResource(proxy_url, proxied_endpoint_str, proxied_url, request, reactor=self.reactor, origin=origin, verbose=self.verbose) return resource return None def mod_cookies(self, value_list): proxied_path = self.proxied_path proxied_path_size = len(proxied_path) results = [] for cookie_value in value_list: c = Cookie.SimpleCookie() c.load(cookie_value) for k in c.keys(): m = c[k] if m.has_key('path'): m_path = m['path'] if self.is_proxy_path_or_child(m_path): m_path = m_path[proxied_path_size:] m['path'] = m_path results.append(c.output(header='')[1:]) return results def is_proxy_path_or_child(self, path): return proxyutils.is_proxy_path_or_child(self.proxied_path, path) def proxied_url_to_proxy_url(self, proxy_scheme, target_url): return proxyutils.proxied_url_to_proxy_url(proxy_scheme, self.fqdn, self.port, self.proxied_netloc, self.proxied_path, target_url) def proxy_url_to_proxied_url(self, target_url): return proxyutils.proxy_url_to_proxied_url(self.proxied_scheme, self.fqdn, self.port, self.proxied_netloc, self.proxied_path, target_url) def get_template_static_base(self): if self.template_resource is None: return None else: return '{0}static/'.format(self.template_resource) def render_template_403(self, request, **kwargs): template_dir = self.template_dir if template_dir is None: request.setResponseCode(403) return "" else: return self.render_template('error/403.jinja2', request=request, **kwargs) def render_template_500(self, request, **kwargs): template_dir = self.template_dir if template_dir is None: request.setResponseCode(500) return "" else: return self.render_template('error/500.jinja2', request=request, **kwargs) def render_template(self, template_name, **kwargs): template_dir = self.template_dir try: template = self.template_loader_.load(self.template_env_, template_name) except TemplateNotFound: raise Exception( "The template '{0}' was not found.".format(template_name)) return template.render(static_base=self.static_base, **kwargs).encode('utf-8') def create_template_static_resource(self): static_path = os.path.join(self.template_dir, 'static') static = File(static_path) return static def static(self, request): return self.templateStaticResource_ @app.handle_errors(Exception) def handle_uncaught_errors(self, request, failure): self.log("Uncaught exception: {0}".format(failure), important=True) return self.render_template_500(request=request, failure=failure)
""" Takes a jsonresume file and formats in in markdown """ import os import json from jinja2 import Environment, FileSystemLoader dirname = os.path.dirname(os.path.abspath(__file__)) with open('resume.json') as fd: resume = json.loads(fd.read()) env = Environment() loader = FileSystemLoader(dirname) tmpl = loader.load(env, 'resume.tmpl') context = dict(resume) print tmpl.render(context)