From 6cdfb2110b0f96502eeaaf98f59a05704534cdff Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Fri, 18 Nov 2016 13:47:32 +0100 Subject: serve signup page through twisted --- service/pixelated/resources/login_resource.py | 13 +++++++++++++ service/pixelated/resources/root_resource.py | 14 ++++++++++++++ 2 files changed, 27 insertions(+) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index d5555b90..905b872c 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -39,6 +39,17 @@ def _get_startup_folder(): return os.path.join(path, '..', 'assets') +def _get_public_folder(): + static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "public")) + # this is a workaround for packaging + if not os.path.exists(static_folder): + static_folder = os.path.abspath( + os.path.join(os.path.abspath(__file__), "..", "..", "..", "..", "web-ui", "public")) + if not os.path.exists(static_folder): + static_folder = os.path.join('/', 'usr', 'share', 'pixelated-user-agent') + return static_folder + + def _get_static_folder(): static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "app")) # this is a workaround for packaging @@ -107,6 +118,7 @@ class LoginResource(BaseResource): def __init__(self, services_factory, provider=None, disclaimer_banner=None, authenticator=None): BaseResource.__init__(self, services_factory) self._static_folder = _get_static_folder() + self._public_folder = _get_public_folder() self._startup_folder = _get_startup_folder() self._disclaimer_banner = disclaimer_banner self._provider = provider @@ -114,6 +126,7 @@ class LoginResource(BaseResource): self._bootstrap_user_services = BootstrapUserServices(services_factory, provider) self.putChild('startup-assets', File(self._startup_folder)) + self.putChild('public-assets', File(self._public_folder)) with open(os.path.join(self._startup_folder, 'Interstitial.html')) as f: self.interstitial = f.read() diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 8df76c70..8fa80bb2 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -51,6 +51,7 @@ class RootResource(BaseResource): def __init__(self, services_factory): BaseResource.__init__(self, services_factory) self._startup_assets_folder = self._get_startup_folder() + self._public_assets_folder = self._get_public_folder() self._static_folder = self._get_static_folder() self._html_template = open(os.path.join(self._static_folder, 'index.html')).read() self._services_factory = services_factory @@ -61,6 +62,7 @@ class RootResource(BaseResource): def _startup_mode(self): self.putChild('startup-assets', File(self._startup_assets_folder)) + self.putChild('public-assets', File(self._public_assets_folder)) self._mode = MODE_STARTUP def getChild(self, path, request): @@ -106,10 +108,22 @@ class RootResource(BaseResource): self._mode = MODE_RUNNING + # TODO: use the public folder for this def _get_startup_folder(self): path = os.path.dirname(os.path.abspath(__file__)) return os.path.join(path, '..', 'assets') + def _get_public_folder(self): + public_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "public")) + # this is a workaround for packaging + if not os.path.exists(public_folder): + public_folder = os.path.abspath( + os.path.join(os.path.abspath(__file__), "..", "..", "..", "..", "web-ui", "public")) + if not os.path.exists(public_folder): + # TODO: how is this packaged? + public_folder = os.path.join('/', 'usr', 'share', 'pixelated-user-agent') + return public_folder + def _get_static_folder(self): static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "app")) # this is a workaround for packaging -- cgit v1.2.3 From b00b7ff5d828099e8f0190fee44ad1daf2054717 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Thu, 24 Nov 2016 16:41:49 +0100 Subject: add public root resource to serve static files --- service/pixelated/resources/auth.py | 2 +- service/pixelated/resources/root_resource.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/auth.py b/service/pixelated/resources/auth.py index adac985f..ef5c9710 100644 --- a/service/pixelated/resources/auth.py +++ b/service/pixelated/resources/auth.py @@ -108,7 +108,7 @@ class PixelatedAuthSessionWrapper(object): else: log.err( result, - "HTTPAuthSessionWrapper.getChildWithDefault encountered " + "PixelatedAuthSessionWrapper.getChildWithDefault encountered " "unexpected error") return ErrorPage(500, None, None) diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 8fa80bb2..608e18ef 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -47,6 +47,18 @@ MODE_STARTUP = 1 MODE_RUNNING = 2 +class PublicRootResource(BaseResource, object): + + def __init__(self, services_factory, assets_path): + super(PublicRootResource, self).__init__(services_factory) + self._child_resources = dict( + assets=File(assets_path) + ) + + def getChild(self, path, request): + return self._child_resources.get(path) or NoResource() + + class RootResource(BaseResource): def __init__(self, services_factory): BaseResource.__init__(self, services_factory) -- cgit v1.2.3 From 7802cf70c3b2ec3c14fd735dc211b00914c731cb Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Thu, 24 Nov 2016 17:01:15 +0100 Subject: add login resource as child of public root resource --- service/pixelated/resources/root_resource.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 608e18ef..5477dca8 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -49,10 +49,11 @@ MODE_RUNNING = 2 class PublicRootResource(BaseResource, object): - def __init__(self, services_factory, assets_path): + def __init__(self, services_factory, assets_path, **kwargs): super(PublicRootResource, self).__init__(services_factory) self._child_resources = dict( - assets=File(assets_path) + assets=File(assets_path), + login=LoginResource(services_factory, **{k: kwargs[k] for k in kwargs if k in ('provider', 'disclaimer_banner', 'authenticator')}) ) def getChild(self, path, request): -- cgit v1.2.3 From e313d7c8880192ab3261cdd8cb263f5eef28d40a Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Fri, 25 Nov 2016 15:50:50 +0100 Subject: make credentialsFactories parameter to auth session wrapper optional --- service/pixelated/resources/auth.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/auth.py b/service/pixelated/resources/auth.py index ef5c9710..833c0f9d 100644 --- a/service/pixelated/resources/auth.py +++ b/service/pixelated/resources/auth.py @@ -75,7 +75,7 @@ class PixelatedAuthSessionWrapper(object): isLeaf = False - def __init__(self, portal, root_resource, anonymous_resource, credentialFactories): + def __init__(self, portal, root_resource, anonymous_resource, credentialFactories=[]): self._portal = portal self._credentialFactories = credentialFactories self._root_resource = root_resource -- cgit v1.2.3 From 77cc41204e3cd8144187ad8cf50fffb3d00080f1 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Mon, 28 Nov 2016 12:00:06 +0100 Subject: split inbox resource out of root resource --- service/pixelated/resources/root_resource.py | 127 ++++++++++++--------------- 1 file changed, 58 insertions(+), 69 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 5477dca8..d35147f5 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -19,6 +19,7 @@ import os from string import Template from pixelated.resources.users import UsersResource +import pixelated from pixelated.resources import BaseResource, UnAuthorizedResource, UnavailableResource from pixelated.resources import IPixelatedSession from pixelated.resources.attachments_resource import AttachmentsResource @@ -47,44 +48,66 @@ MODE_STARTUP = 1 MODE_RUNNING = 2 -class PublicRootResource(BaseResource, object): +class InboxResource(BaseResource): + isLeaf = True - def __init__(self, services_factory, assets_path, **kwargs): - super(PublicRootResource, self).__init__(services_factory) - self._child_resources = dict( - assets=File(assets_path), - login=LoginResource(services_factory, **{k: kwargs[k] for k in kwargs if k in ('provider', 'disclaimer_banner', 'authenticator')}) - ) + def __init__(self, services_factory): + BaseResource.__init__(self, services_factory) + self._templates_folder = self._get_templates_folder() + self._html_template = open(os.path.join(self._templates_folder, 'index.html')).read() + with open(os.path.join(self._templates_folder, 'Interstitial.html')) as f: + self.interstitial = f.read() + self._mode = MODE_STARTUP + + def initialize(self): + self._mode = MODE_RUNNING - def getChild(self, path, request): - return self._child_resources.get(path) or NoResource() + def _get_templates_folder(self): + path = os.path.dirname(os.path.abspath(pixelated.__file__)) + return os.path.join(path, 'assets') + + def _add_csrf_cookie(self, request): + csrf_token = hashlib.sha256(os.urandom(CSRF_TOKEN_LENGTH)).hexdigest() + request.addCookie('XSRF-TOKEN', csrf_token) + + def _is_starting(self): + return self._mode == MODE_STARTUP + + def render_GET(self, request): + self._add_csrf_cookie(request) + if self._is_starting(): + return self.interstitial + else: + account_email = self.mail_service(request).account_email + response = Template(self._html_template).safe_substitute(account_email=account_email) + return str(response) class RootResource(BaseResource): def __init__(self, services_factory): BaseResource.__init__(self, services_factory) + self._assets_folder = self._get_assets_folder() self._startup_assets_folder = self._get_startup_folder() - self._public_assets_folder = self._get_public_folder() self._static_folder = self._get_static_folder() self._html_template = open(os.path.join(self._static_folder, 'index.html')).read() self._services_factory = services_factory - self._child_resources = ChildResourcesMap() with open(os.path.join(self._startup_assets_folder, 'Interstitial.html')) as f: self.interstitial = f.read() + self._inbox_resource = InboxResource(services_factory) self._startup_mode() def _startup_mode(self): + self.putChild('assets', File(self._assets_folder)) self.putChild('startup-assets', File(self._startup_assets_folder)) - self.putChild('public-assets', File(self._public_assets_folder)) self._mode = MODE_STARTUP - def getChild(self, path, request): + def getChildWithDefault(self, path, request): if path == '': - return self + return self._inbox_resource if self._mode == MODE_STARTUP: return UnavailableResource() if self._is_xsrf_valid(request): - return self._child_resources.get(path) + return BaseResource.getChildWithDefault(self, path, request) return UnAuthorizedResource() def _is_xsrf_valid(self, request): @@ -103,40 +126,33 @@ class RootResource(BaseResource): return csrf_input and csrf_input == xsrf_token def initialize(self, provider=None, disclaimer_banner=None, authenticator=None): - self._child_resources.add('sandbox', SandboxResource(self._static_folder)) - self._child_resources.add('assets', File(self._static_folder)) - self._child_resources.add('keys', KeysResource(self._services_factory)) - self._child_resources.add(AttachmentsResource.BASE_URL, AttachmentsResource(self._services_factory)) - self._child_resources.add('contacts', ContactsResource(self._services_factory)) - self._child_resources.add('features', FeaturesResource(provider)) - self._child_resources.add('tags', TagsResource(self._services_factory)) - self._child_resources.add('mails', MailsResource(self._services_factory)) - self._child_resources.add('mail', MailResource(self._services_factory)) - self._child_resources.add('feedback', FeedbackResource(self._services_factory)) - self._child_resources.add('user-settings', UserSettingsResource(self._services_factory)) - self._child_resources.add('users', UsersResource(self._services_factory)) - self._child_resources.add(LoginResource.BASE_URL, - LoginResource(self._services_factory, provider, disclaimer_banner=disclaimer_banner, authenticator=authenticator)) - self._child_resources.add(LogoutResource.BASE_URL, LogoutResource(self._services_factory)) - + self.putChild('sandbox', SandboxResource(self._static_folder)) + self.putChild('keys', KeysResource(self._services_factory)) + self.putChild(AttachmentsResource.BASE_URL, AttachmentsResource(self._services_factory)) + self.putChild('contacts', ContactsResource(self._services_factory)) + self.putChild('features', FeaturesResource(provider)) + self.putChild('tags', TagsResource(self._services_factory)) + self.putChild('mails', MailsResource(self._services_factory)) + self.putChild('mail', MailResource(self._services_factory)) + self.putChild('feedback', FeedbackResource(self._services_factory)) + self.putChild('user-settings', UserSettingsResource(self._services_factory)) + self.putChild('users', UsersResource(self._services_factory)) + self.putChild(LoginResource.BASE_URL, + LoginResource(self._services_factory, provider, disclaimer_banner=disclaimer_banner, authenticator=authenticator)) + self.putChild(LogoutResource.BASE_URL, LogoutResource(self._services_factory)) + + self._inbox_resource.initialize() self._mode = MODE_RUNNING + def _get_assets_folder(self): + pixelated_path = os.path.dirname(os.path.abspath(pixelated.__file__)) + return os.path.join(pixelated_path, '..', '..', 'web-ui', 'public') + # TODO: use the public folder for this def _get_startup_folder(self): path = os.path.dirname(os.path.abspath(__file__)) return os.path.join(path, '..', 'assets') - def _get_public_folder(self): - public_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "public")) - # this is a workaround for packaging - if not os.path.exists(public_folder): - public_folder = os.path.abspath( - os.path.join(os.path.abspath(__file__), "..", "..", "..", "..", "web-ui", "public")) - if not os.path.exists(public_folder): - # TODO: how is this packaged? - public_folder = os.path.join('/', 'usr', 'share', 'pixelated-user-agent') - return public_folder - def _get_static_folder(self): static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "app")) # this is a workaround for packaging @@ -146,30 +162,3 @@ class RootResource(BaseResource): if not os.path.exists(static_folder): static_folder = os.path.join('/', 'usr', 'share', 'pixelated-user-agent') return static_folder - - def _is_starting(self): - return self._mode == MODE_STARTUP - - def _add_csrf_cookie(self, request): - csrf_token = hashlib.sha256(os.urandom(CSRF_TOKEN_LENGTH)).hexdigest() - request.addCookie('XSRF-TOKEN', csrf_token) - - def render_GET(self, request): - self._add_csrf_cookie(request) - if self._is_starting(): - return self.interstitial - else: - account_email = self.mail_service(request).account_email - response = Template(self._html_template).safe_substitute(account_email=account_email) - return str(response) - - -class ChildResourcesMap(object): - def __init__(self): - self._registry = {} - - def add(self, path, resource): - self._registry[path] = resource - - def get(self, path): - return self._registry.get(path) or NoResource() -- cgit v1.2.3 From b50db20c0a6603a3ea5f0b704baee1983fc34c1d Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Tue, 29 Nov 2016 10:16:38 +0100 Subject: return resource instead of username/avatarId as avatar --- service/pixelated/resources/auth.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/auth.py b/service/pixelated/resources/auth.py index 833c0f9d..a2054f18 100644 --- a/service/pixelated/resources/auth.py +++ b/service/pixelated/resources/auth.py @@ -64,10 +64,18 @@ class SessionChecker(object): class PixelatedRealm(object): implements(portal.IRealm) + def __init__(self, authenticated_resource, public_resource): + self._authenticated_resource = authenticated_resource + self._public_resource = public_resource + def requestAvatar(self, avatarId, mind, *interfaces): - if IResource in interfaces: - return IResource, avatarId, lambda: None - raise NotImplementedError() + if IResource not in interfaces: + raise NotImplementedError() + if avatarId == checkers.ANONYMOUS: + avatar = self._public_resource + else: + avatar = self._authenticated_resource + return IResource, avatar, lambda: None @implementer(IResource) @@ -93,23 +101,18 @@ class PixelatedAuthSessionWrapper(object): return util.DeferredResource(self._login(creds, request)) def _login(self, credentials, request): - pattern = re.compile("^/sandbox/") - def loginSucceeded(args): interface, avatar, logout = args - if avatar == checkers.ANONYMOUS and not pattern.match(request.path): - return self._anonymous_resource - else: - return self._root_resource + # TODO: make sandbox public + return avatar def loginFailed(result): if result.check(error.Unauthorized, error.LoginFailed): return UnauthorizedResource(self._credentialFactories) else: - log.err( - result, + log.error( "PixelatedAuthSessionWrapper.getChildWithDefault encountered " - "unexpected error") + "unexpected error: %s" % result) return ErrorPage(500, None, None) d = self._portal.login(credentials, None, IResource) -- cgit v1.2.3 From 0bb7304f7cb87aed31f588bf40ae0a7fd949c2ba Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Tue, 29 Nov 2016 11:10:26 +0100 Subject: move adding csrf to base resource --- service/pixelated/resources/__init__.py | 10 +++++- service/pixelated/resources/root_resource.py | 52 +++++----------------------- 2 files changed, 18 insertions(+), 44 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/__init__.py b/service/pixelated/resources/__init__.py index 11611f0b..97346a6f 100644 --- a/service/pixelated/resources/__init__.py +++ b/service/pixelated/resources/__init__.py @@ -13,8 +13,9 @@ # # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see . - +import hashlib import json +import os from twisted.web.http import UNAUTHORIZED from twisted.web.resource import Resource @@ -26,6 +27,8 @@ from twisted.web.http import INTERNAL_SERVER_ERROR, SERVICE_UNAVAILABLE log = Logger() +CSRF_TOKEN_LENGTH = 32 + class SetEncoder(json.JSONEncoder): def default(self, obj): @@ -62,6 +65,11 @@ class BaseResource(Resource): Resource.__init__(self) self._services_factory = services_factory + def _add_csrf_cookie(self, request): + csrf_token = hashlib.sha256(os.urandom(CSRF_TOKEN_LENGTH)).hexdigest() + request.addCookie('XSRF-TOKEN', csrf_token) + log.debug('XSRF-TOKEN added: %s' % csrf_token) + def _get_user_id_from_request(self, request): if self._services_factory.mode.is_single_user: return None # it doesn't matter diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index d35147f5..e5b4227f 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -13,10 +13,8 @@ # # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see . -import hashlib import json import os -from string import Template from pixelated.resources.users import UsersResource import pixelated @@ -34,56 +32,20 @@ from pixelated.resources.mail_resource import MailResource from pixelated.resources.mails_resource import MailsResource from pixelated.resources.tags_resource import TagsResource from pixelated.resources.keys_resource import KeysResource +from pixelated.resources.inbox_resource import InboxResource, MODE_STARTUP, MODE_RUNNING from twisted.web.resource import NoResource from twisted.web.static import File from twisted.logger import Logger -log = Logger() +logger = Logger() -CSRF_TOKEN_LENGTH = 32 +class PublicRootResource(BaseResource): + pass -MODE_STARTUP = 1 -MODE_RUNNING = 2 - -class InboxResource(BaseResource): - isLeaf = True - - def __init__(self, services_factory): - BaseResource.__init__(self, services_factory) - self._templates_folder = self._get_templates_folder() - self._html_template = open(os.path.join(self._templates_folder, 'index.html')).read() - with open(os.path.join(self._templates_folder, 'Interstitial.html')) as f: - self.interstitial = f.read() - self._mode = MODE_STARTUP - - def initialize(self): - self._mode = MODE_RUNNING - - def _get_templates_folder(self): - path = os.path.dirname(os.path.abspath(pixelated.__file__)) - return os.path.join(path, 'assets') - - def _add_csrf_cookie(self, request): - csrf_token = hashlib.sha256(os.urandom(CSRF_TOKEN_LENGTH)).hexdigest() - request.addCookie('XSRF-TOKEN', csrf_token) - - def _is_starting(self): - return self._mode == MODE_STARTUP - - def render_GET(self, request): - self._add_csrf_cookie(request) - if self._is_starting(): - return self.interstitial - else: - account_email = self.mail_service(request).account_email - response = Template(self._html_template).safe_substitute(account_email=account_email) - return str(response) - - -class RootResource(BaseResource): +class RootResource(PublicRootResource): def __init__(self, services_factory): BaseResource.__init__(self, services_factory) self._assets_folder = self._get_assets_folder() @@ -100,6 +62,7 @@ class RootResource(BaseResource): self.putChild('assets', File(self._assets_folder)) self.putChild('startup-assets', File(self._startup_assets_folder)) self._mode = MODE_STARTUP + logger.debug('Root in STARTUP mode. %s' % self) def getChildWithDefault(self, path, request): if path == '': @@ -116,7 +79,9 @@ class RootResource(BaseResource): return True xsrf_token = request.getCookie('XSRF-TOKEN') + logger.debug('CSRF token: %s' % xsrf_token) + # TODO: how is comparing the cookie-csrf with the HTTP-header-csrf adding any csrf protection? ajax_request = (request.getHeader('x-requested-with') == 'XMLHttpRequest') if ajax_request: xsrf_header = request.getHeader('x-xsrf-token') @@ -143,6 +108,7 @@ class RootResource(BaseResource): self._inbox_resource.initialize() self._mode = MODE_RUNNING + logger.debug('Root in RUNNING mode. %s' % self) def _get_assets_folder(self): pixelated_path = os.path.dirname(os.path.abspath(pixelated.__file__)) -- cgit v1.2.3 From cec3cbf731f0e56cb96de27a070bdaf72e985eb0 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Tue, 29 Nov 2016 11:40:21 +0100 Subject: root resource inherits from public root --- service/pixelated/resources/root_resource.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index e5b4227f..0788ffb1 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -42,12 +42,15 @@ logger = Logger() class PublicRootResource(BaseResource): - pass + + def __init__(self, services_factory): + BaseResource.__init__(self, services_factory) class RootResource(PublicRootResource): + def __init__(self, services_factory): - BaseResource.__init__(self, services_factory) + PublicRootResource.__init__(self, services_factory) self._assets_folder = self._get_assets_folder() self._startup_assets_folder = self._get_startup_folder() self._static_folder = self._get_static_folder() -- cgit v1.2.3 From 3f97f5c444ea4caa01111f3902871975430d9d97 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Tue, 29 Nov 2016 17:34:41 +0100 Subject: add inbox resource --- service/pixelated/resources/inbox_resource.py | 64 +++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 service/pixelated/resources/inbox_resource.py (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/inbox_resource.py b/service/pixelated/resources/inbox_resource.py new file mode 100644 index 00000000..47a3c072 --- /dev/null +++ b/service/pixelated/resources/inbox_resource.py @@ -0,0 +1,64 @@ +# +# Copyright (c) 2016 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +import hashlib +import os +from string import Template + +import pixelated +from pixelated.resources import BaseResource + +from twisted.logger import Logger + +logger = Logger() + + +MODE_STARTUP = 1 +MODE_RUNNING = 2 + + +class InboxResource(BaseResource): + isLeaf = True + + def __init__(self, services_factory): + BaseResource.__init__(self, services_factory) + self._templates_folder = self._get_templates_folder() + self._html_template = open(os.path.join(self._templates_folder, 'index.html')).read() + with open(os.path.join(self._templates_folder, 'Interstitial.html')) as f: + self.interstitial = f.read() + self._mode = MODE_STARTUP + + def initialize(self): + self._mode = MODE_RUNNING + logger.debug('Inbox in RUNNING mode. %s' % self) + + def _get_templates_folder(self): + path = os.path.dirname(os.path.abspath(pixelated.__file__)) + return os.path.join(path, 'assets') + + def _is_starting(self): + return self._mode == MODE_STARTUP + + def render_GET(self, request): + logger.debug('Inbox rendering GET. %s' % self) + self._add_csrf_cookie(request) + if self._is_starting(): + logger.debug('Inbox rendering interstitial. %s' % self) + return self.interstitial + else: + logger.debug('Inbox rendering from template. %s' % self) + account_email = self.mail_service(request).account_email + response = Template(self._html_template).safe_substitute(account_email=account_email) + return str(response) -- cgit v1.2.3 From 9b5d5a797c9f407183d1b9a6a2aea552a06c5ea1 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Tue, 29 Nov 2016 17:47:07 +0100 Subject: make login resource part of the public root resource --- service/pixelated/resources/root_resource.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 0788ffb1..24d097f9 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -46,6 +46,10 @@ class PublicRootResource(BaseResource): def __init__(self, services_factory): BaseResource.__init__(self, services_factory) + def initialize(self, provider=None, disclaimer_banner=None, authenticator=None): + self.putChild(LoginResource.BASE_URL, + LoginResource(self._services_factory, provider, disclaimer_banner=disclaimer_banner, authenticator=authenticator)) + class RootResource(PublicRootResource): @@ -94,6 +98,7 @@ class RootResource(PublicRootResource): return csrf_input and csrf_input == xsrf_token def initialize(self, provider=None, disclaimer_banner=None, authenticator=None): + PublicRootResource.initialize(self, provider, disclaimer_banner, authenticator) self.putChild('sandbox', SandboxResource(self._static_folder)) self.putChild('keys', KeysResource(self._services_factory)) self.putChild(AttachmentsResource.BASE_URL, AttachmentsResource(self._services_factory)) @@ -105,8 +110,6 @@ class RootResource(PublicRootResource): self.putChild('feedback', FeedbackResource(self._services_factory)) self.putChild('user-settings', UserSettingsResource(self._services_factory)) self.putChild('users', UsersResource(self._services_factory)) - self.putChild(LoginResource.BASE_URL, - LoginResource(self._services_factory, provider, disclaimer_banner=disclaimer_banner, authenticator=authenticator)) self.putChild(LogoutResource.BASE_URL, LogoutResource(self._services_factory)) self._inbox_resource.initialize() -- cgit v1.2.3 From c10c6fb76f06e0cfc6f061a1bd9df14d689fb176 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Wed, 30 Nov 2016 10:29:27 +0100 Subject: redirect to login from root url when not logged in --- service/pixelated/resources/root_resource.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 24d097f9..035d5f18 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -35,6 +35,7 @@ from pixelated.resources.keys_resource import KeysResource from pixelated.resources.inbox_resource import InboxResource, MODE_STARTUP, MODE_RUNNING from twisted.web.resource import NoResource from twisted.web.static import File +from twisted.web.util import Redirect from twisted.logger import Logger @@ -45,11 +46,17 @@ class PublicRootResource(BaseResource): def __init__(self, services_factory): BaseResource.__init__(self, services_factory) + self._redirect_to_inbox_resource = Redirect('login') def initialize(self, provider=None, disclaimer_banner=None, authenticator=None): self.putChild(LoginResource.BASE_URL, LoginResource(self._services_factory, provider, disclaimer_banner=disclaimer_banner, authenticator=authenticator)) + def getChildWithDefault(self, path, request): + if path == '': + return self._redirect_to_inbox_resource + return BaseResource.getChildWithDefault(self, path, request) + class RootResource(PublicRootResource): -- cgit v1.2.3 From 41f0886aeac43387dc8b4d54b1ca69f21e2ec2a8 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Wed, 30 Nov 2016 15:00:58 +0100 Subject: remove PublicRootResource and use a flag on RootResource instead --- service/pixelated/resources/root_resource.py | 62 +++++++++++++--------------- 1 file changed, 28 insertions(+), 34 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 035d5f18..3f09848f 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -42,26 +42,11 @@ from twisted.logger import Logger logger = Logger() -class PublicRootResource(BaseResource): +class RootResource(BaseResource): - def __init__(self, services_factory): + def __init__(self, services_factory, public=False): BaseResource.__init__(self, services_factory) - self._redirect_to_inbox_resource = Redirect('login') - - def initialize(self, provider=None, disclaimer_banner=None, authenticator=None): - self.putChild(LoginResource.BASE_URL, - LoginResource(self._services_factory, provider, disclaimer_banner=disclaimer_banner, authenticator=authenticator)) - - def getChildWithDefault(self, path, request): - if path == '': - return self._redirect_to_inbox_resource - return BaseResource.getChildWithDefault(self, path, request) - - -class RootResource(PublicRootResource): - - def __init__(self, services_factory): - PublicRootResource.__init__(self, services_factory) + self._public = public self._assets_folder = self._get_assets_folder() self._startup_assets_folder = self._get_startup_folder() self._static_folder = self._get_static_folder() @@ -69,18 +54,19 @@ class RootResource(PublicRootResource): self._services_factory = services_factory with open(os.path.join(self._startup_assets_folder, 'Interstitial.html')) as f: self.interstitial = f.read() + self._redirect_to_login_resource = Redirect('login') self._inbox_resource = InboxResource(services_factory) self._startup_mode() def _startup_mode(self): - self.putChild('assets', File(self._assets_folder)) - self.putChild('startup-assets', File(self._startup_assets_folder)) + self.putChildProtected('assets', File(self._assets_folder)) + self.putChildPublic('startup-assets', File(self._startup_assets_folder)) self._mode = MODE_STARTUP logger.debug('Root in STARTUP mode. %s' % self) def getChildWithDefault(self, path, request): if path == '': - return self._inbox_resource + return self._redirect_to_login_resource if self._public else self._inbox_resource if self._mode == MODE_STARTUP: return UnavailableResource() if self._is_xsrf_valid(request): @@ -104,20 +90,28 @@ class RootResource(PublicRootResource): csrf_input = request.args.get('csrftoken', [None])[0] or json.loads(request.content.read()).get('csrftoken', [None])[0] return csrf_input and csrf_input == xsrf_token + def putChildPublic(self, path, resource): + return BaseResource.putChild(self, path, resource) + + def putChildProtected(self, path, resource): + return BaseResource.putChild(self, path, UnAuthorizedResource() if self._public else resource) + putChild = putChildProtected + def initialize(self, provider=None, disclaimer_banner=None, authenticator=None): - PublicRootResource.initialize(self, provider, disclaimer_banner, authenticator) - self.putChild('sandbox', SandboxResource(self._static_folder)) - self.putChild('keys', KeysResource(self._services_factory)) - self.putChild(AttachmentsResource.BASE_URL, AttachmentsResource(self._services_factory)) - self.putChild('contacts', ContactsResource(self._services_factory)) - self.putChild('features', FeaturesResource(provider)) - self.putChild('tags', TagsResource(self._services_factory)) - self.putChild('mails', MailsResource(self._services_factory)) - self.putChild('mail', MailResource(self._services_factory)) - self.putChild('feedback', FeedbackResource(self._services_factory)) - self.putChild('user-settings', UserSettingsResource(self._services_factory)) - self.putChild('users', UsersResource(self._services_factory)) - self.putChild(LogoutResource.BASE_URL, LogoutResource(self._services_factory)) + self.putChildProtected('sandbox', SandboxResource(self._static_folder)) + self.putChildProtected('keys', KeysResource(self._services_factory)) + self.putChildProtected(AttachmentsResource.BASE_URL, AttachmentsResource(self._services_factory)) + self.putChildProtected('contacts', ContactsResource(self._services_factory)) + self.putChildProtected('features', FeaturesResource(provider)) + self.putChildProtected('tags', TagsResource(self._services_factory)) + self.putChildProtected('mails', MailsResource(self._services_factory)) + self.putChildProtected('mail', MailResource(self._services_factory)) + self.putChildProtected('feedback', FeedbackResource(self._services_factory)) + self.putChildProtected('user-settings', UserSettingsResource(self._services_factory)) + self.putChildProtected('users', UsersResource(self._services_factory)) + self.putChildPublic(LoginResource.BASE_URL, + LoginResource(self._services_factory, provider, disclaimer_banner=disclaimer_banner, authenticator=authenticator)) + self.putChildProtected(LogoutResource.BASE_URL, LogoutResource(self._services_factory)) self._inbox_resource.initialize() self._mode = MODE_RUNNING -- cgit v1.2.3 From a493da72d53fe90d679d7fa1980dd185415d9be3 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Wed, 30 Nov 2016 15:07:52 +0100 Subject: log a warnin when root child is not explicitly public/protected --- service/pixelated/resources/root_resource.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 3f09848f..7d5b0b0a 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -95,7 +95,10 @@ class RootResource(BaseResource): def putChildProtected(self, path, resource): return BaseResource.putChild(self, path, UnAuthorizedResource() if self._public else resource) - putChild = putChildProtected + + def putChild(self, path, resource): + logger.warn('Use either `putChildPublic` or `putChildProtected` on this resource') + return self.putChildProtected(path, resource) # to be on the safe side def initialize(self, provider=None, disclaimer_banner=None, authenticator=None): self.putChildProtected('sandbox', SandboxResource(self._static_folder)) -- cgit v1.2.3 From 13378255c02b97184132881599ed47826963f54a Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Wed, 30 Nov 2016 16:11:27 +0100 Subject: add csrf token to login form --- service/pixelated/resources/login_resource.py | 6 ++++++ service/pixelated/resources/session.py | 10 ++++++++++ 2 files changed, 16 insertions(+) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index fec4307e..7d61ddce 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -107,6 +107,11 @@ class LoginWebSite(Element): return tag(self._error_msg) return tag('') + @renderer + def csrftoken(self, request, tag): + tag.fillSlots(csrftoken=IPixelatedSession(request.getSession()).get_csrf_token()) + return tag + @renderer def disclaimer(self, request, tag): return DisclaimerElement(self.disclaimer_banner_file).render(request) @@ -140,6 +145,7 @@ class LoginResource(BaseResource): return NoResource() def render_GET(self, request): + request.getSession() request.setResponseCode(OK) return self._render_template(request) diff --git a/service/pixelated/resources/session.py b/service/pixelated/resources/session.py index 9ade8d29..0e46ad8f 100644 --- a/service/pixelated/resources/session.py +++ b/service/pixelated/resources/session.py @@ -13,11 +13,15 @@ # # You should have received a copy of the GNU Affero General Public License # along with Pixelated. If not, see . +import hashlib +import os from zope.interface import Interface, Attribute, implements from twisted.python.components import registerAdapter from twisted.web.server import Session +CSRF_TOKEN_LENGTH = 32 + class IPixelatedSession(Interface): user_uuid = Attribute('The uuid of the currently logged in user') @@ -28,6 +32,7 @@ class PixelatedSession(object): def __init__(self, session): self.user_uuid = None + self._csrf_token = None def is_logged_in(self): return self.user_uuid is not None @@ -35,5 +40,10 @@ class PixelatedSession(object): def expire(self): self.user_uuid = None + def get_csrf_token(self): + if self._csrf_token is None: + self._csrf_token = hashlib.sha256(os.urandom(CSRF_TOKEN_LENGTH)).hexdigest() + return self._csrf_token + registerAdapter(PixelatedSession, Session, IPixelatedSession) -- cgit v1.2.3 From 770b439c8495c3a0b16550c2f04740f31646d66b Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Thu, 1 Dec 2016 10:36:29 +0100 Subject: WIP: add csrf token to every request --- service/pixelated/resources/__init__.py | 2 +- service/pixelated/resources/inbox_resource.py | 1 - service/pixelated/resources/root_resource.py | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/__init__.py b/service/pixelated/resources/__init__.py index 97346a6f..023758de 100644 --- a/service/pixelated/resources/__init__.py +++ b/service/pixelated/resources/__init__.py @@ -66,7 +66,7 @@ class BaseResource(Resource): self._services_factory = services_factory def _add_csrf_cookie(self, request): - csrf_token = hashlib.sha256(os.urandom(CSRF_TOKEN_LENGTH)).hexdigest() + csrf_token = IPixelatedSession(request.getSession()).get_csrf_token() request.addCookie('XSRF-TOKEN', csrf_token) log.debug('XSRF-TOKEN added: %s' % csrf_token) diff --git a/service/pixelated/resources/inbox_resource.py b/service/pixelated/resources/inbox_resource.py index 47a3c072..f759dca9 100644 --- a/service/pixelated/resources/inbox_resource.py +++ b/service/pixelated/resources/inbox_resource.py @@ -53,7 +53,6 @@ class InboxResource(BaseResource): def render_GET(self, request): logger.debug('Inbox rendering GET. %s' % self) - self._add_csrf_cookie(request) if self._is_starting(): logger.debug('Inbox rendering interstitial. %s' % self) return self.interstitial diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 7d5b0b0a..1d32935b 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -65,6 +65,7 @@ class RootResource(BaseResource): logger.debug('Root in STARTUP mode. %s' % self) def getChildWithDefault(self, path, request): + self._add_csrf_cookie(request) if path == '': return self._redirect_to_login_resource if self._public else self._inbox_resource if self._mode == MODE_STARTUP: @@ -81,7 +82,6 @@ class RootResource(BaseResource): xsrf_token = request.getCookie('XSRF-TOKEN') logger.debug('CSRF token: %s' % xsrf_token) - # TODO: how is comparing the cookie-csrf with the HTTP-header-csrf adding any csrf protection? ajax_request = (request.getHeader('x-requested-with') == 'XMLHttpRequest') if ajax_request: xsrf_header = request.getHeader('x-xsrf-token') @@ -101,7 +101,7 @@ class RootResource(BaseResource): return self.putChildProtected(path, resource) # to be on the safe side def initialize(self, provider=None, disclaimer_banner=None, authenticator=None): - self.putChildProtected('sandbox', SandboxResource(self._static_folder)) + self.putChildPublic('sandbox', SandboxResource(self._static_folder)) self.putChildProtected('keys', KeysResource(self._services_factory)) self.putChildProtected(AttachmentsResource.BASE_URL, AttachmentsResource(self._services_factory)) self.putChildProtected('contacts', ContactsResource(self._services_factory)) @@ -114,7 +114,7 @@ class RootResource(BaseResource): self.putChildProtected('users', UsersResource(self._services_factory)) self.putChildPublic(LoginResource.BASE_URL, LoginResource(self._services_factory, provider, disclaimer_banner=disclaimer_banner, authenticator=authenticator)) - self.putChildProtected(LogoutResource.BASE_URL, LogoutResource(self._services_factory)) + self.putChildPublic(LogoutResource.BASE_URL, LogoutResource(self._services_factory)) self._inbox_resource.initialize() self._mode = MODE_RUNNING -- cgit v1.2.3 From 165ab49e41faa7ba7d524c58b3b0d383a4c9a2d9 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Thu, 1 Dec 2016 17:35:33 +0100 Subject: use the right inbox template --- service/pixelated/resources/inbox_resource.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/inbox_resource.py b/service/pixelated/resources/inbox_resource.py index f759dca9..426de5cc 100644 --- a/service/pixelated/resources/inbox_resource.py +++ b/service/pixelated/resources/inbox_resource.py @@ -34,15 +34,19 @@ class InboxResource(BaseResource): def __init__(self, services_factory): BaseResource.__init__(self, services_factory) + self._not_quite_the_templates_folder = self._get_not_quite_the_templates_folder() self._templates_folder = self._get_templates_folder() - self._html_template = open(os.path.join(self._templates_folder, 'index.html')).read() + self._html_template = open(os.path.join(self._not_quite_the_templates_folder, 'index.html')).read() with open(os.path.join(self._templates_folder, 'Interstitial.html')) as f: self.interstitial = f.read() self._mode = MODE_STARTUP def initialize(self): self._mode = MODE_RUNNING - logger.debug('Inbox in RUNNING mode. %s' % self) + + def _get_not_quite_the_templates_folder(self): + path = os.path.dirname(os.path.abspath(pixelated.__file__)) + return os.path.join(path, '..', '..', 'web-ui', 'app') def _get_templates_folder(self): path = os.path.dirname(os.path.abspath(pixelated.__file__)) @@ -52,12 +56,9 @@ class InboxResource(BaseResource): return self._mode == MODE_STARTUP def render_GET(self, request): - logger.debug('Inbox rendering GET. %s' % self) if self._is_starting(): - logger.debug('Inbox rendering interstitial. %s' % self) return self.interstitial else: - logger.debug('Inbox rendering from template. %s' % self) account_email = self.mail_service(request).account_email response = Template(self._html_template).safe_substitute(account_email=account_email) return str(response) -- cgit v1.2.3 From b14833fbb56bcd5bff0750c16fd9214009b955be Mon Sep 17 00:00:00 2001 From: Zara Gebru Date: Fri, 2 Dec 2016 15:25:23 +0100 Subject: [refactor] move app dir into public dir --- service/pixelated/resources/inbox_resource.py | 2 +- service/pixelated/resources/login_resource.py | 4 ++-- service/pixelated/resources/root_resource.py | 17 ++++------------- 3 files changed, 7 insertions(+), 16 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/inbox_resource.py b/service/pixelated/resources/inbox_resource.py index 426de5cc..d9ba86a5 100644 --- a/service/pixelated/resources/inbox_resource.py +++ b/service/pixelated/resources/inbox_resource.py @@ -46,7 +46,7 @@ class InboxResource(BaseResource): def _get_not_quite_the_templates_folder(self): path = os.path.dirname(os.path.abspath(pixelated.__file__)) - return os.path.join(path, '..', '..', 'web-ui', 'app') + return os.path.join(path, '..', '..', 'web-ui', 'public') def _get_templates_folder(self): path = os.path.dirname(os.path.abspath(pixelated.__file__)) diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index 7d61ddce..6300efdb 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -51,11 +51,11 @@ def _get_public_folder(): def _get_static_folder(): - static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "app")) + static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "public")) # this is a workaround for packaging if not os.path.exists(static_folder): static_folder = os.path.abspath( - os.path.join(os.path.abspath(__file__), "..", "..", "..", "..", "web-ui", "app")) + os.path.join(os.path.abspath(__file__), "..", "..", "..", "..", "web-ui", "public")) if not os.path.exists(static_folder): static_folder = os.path.join('/', 'usr', 'share', 'pixelated-user-agent') return static_folder diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 1d32935b..375f27f6 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -44,13 +44,13 @@ logger = Logger() class RootResource(BaseResource): - def __init__(self, services_factory, public=False): + def __init__(self, services_factory, templates_folder, static_folder, public=False): BaseResource.__init__(self, services_factory) self._public = public self._assets_folder = self._get_assets_folder() self._startup_assets_folder = self._get_startup_folder() - self._static_folder = self._get_static_folder() - self._html_template = open(os.path.join(self._static_folder, 'index.html')).read() + self._static_folder = static_folder + self._html_template = open(os.path.join(templates_folder, 'index.html')).read() self._services_factory = services_factory with open(os.path.join(self._startup_assets_folder, 'Interstitial.html')) as f: self.interstitial = f.read() @@ -61,6 +61,7 @@ class RootResource(BaseResource): def _startup_mode(self): self.putChildProtected('assets', File(self._assets_folder)) self.putChildPublic('startup-assets', File(self._startup_assets_folder)) + self.putChildPublic('static', File(self._static_folder)) self._mode = MODE_STARTUP logger.debug('Root in STARTUP mode. %s' % self) @@ -128,13 +129,3 @@ class RootResource(BaseResource): def _get_startup_folder(self): path = os.path.dirname(os.path.abspath(__file__)) return os.path.join(path, '..', 'assets') - - def _get_static_folder(self): - static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "app")) - # this is a workaround for packaging - if not os.path.exists(static_folder): - static_folder = os.path.abspath( - os.path.join(os.path.abspath(__file__), "..", "..", "..", "..", "web-ui", "app")) - if not os.path.exists(static_folder): - static_folder = os.path.join('/', 'usr', 'share', 'pixelated-user-agent') - return static_folder -- cgit v1.2.3 From 391cc55537a97ec8b2b55662db9c63f86ab885ef Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Mon, 5 Dec 2016 10:32:12 +0100 Subject: get templates from pkg_resources --- service/pixelated/resources/inbox_resource.py | 8 ++------ service/pixelated/resources/login_resource.py | 7 ++++--- service/pixelated/resources/root_resource.py | 6 +++--- 3 files changed, 9 insertions(+), 12 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/inbox_resource.py b/service/pixelated/resources/inbox_resource.py index d9ba86a5..13d1f298 100644 --- a/service/pixelated/resources/inbox_resource.py +++ b/service/pixelated/resources/inbox_resource.py @@ -15,6 +15,7 @@ # along with Pixelated. If not, see . import hashlib import os +import pkg_resources from string import Template import pixelated @@ -35,9 +36,8 @@ class InboxResource(BaseResource): def __init__(self, services_factory): BaseResource.__init__(self, services_factory) self._not_quite_the_templates_folder = self._get_not_quite_the_templates_folder() - self._templates_folder = self._get_templates_folder() self._html_template = open(os.path.join(self._not_quite_the_templates_folder, 'index.html')).read() - with open(os.path.join(self._templates_folder, 'Interstitial.html')) as f: + with open(pkg_resources.resource_filename('templates', 'Interstitial.html')) as f: self.interstitial = f.read() self._mode = MODE_STARTUP @@ -48,10 +48,6 @@ class InboxResource(BaseResource): path = os.path.dirname(os.path.abspath(pixelated.__file__)) return os.path.join(path, '..', '..', 'web-ui', 'public') - def _get_templates_folder(self): - path = os.path.dirname(os.path.abspath(pixelated.__file__)) - return os.path.join(path, 'assets') - def _is_starting(self): return self._mode == MODE_STARTUP diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index 6300efdb..2ca85af9 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -15,6 +15,7 @@ # along with Pixelated. If not, see . import os +import pkg_resources from xml.sax import SAXParseException from pixelated.authentication import Authenticator @@ -71,7 +72,7 @@ def parse_accept_language(all_headers): class DisclaimerElement(Element): - loader = XMLFile(FilePath(os.path.join(_get_startup_folder(), '_login_disclaimer_banner.html'))) + loader = XMLFile(FilePath(pkg_resources.resource_filename('templates', '_login_disclaimer_banner.html'))) def __init__(self, banner): super(DisclaimerElement, self).__init__() @@ -94,7 +95,7 @@ class DisclaimerElement(Element): class LoginWebSite(Element): - loader = XMLFile(FilePath(os.path.join(_get_startup_folder(), 'login.html'))) + loader = XMLFile(FilePath(pkg_resources.resource_filename('templates', 'login.html'))) def __init__(self, error_msg=None, disclaimer_banner_file=None): super(LoginWebSite, self).__init__() @@ -132,7 +133,7 @@ class LoginResource(BaseResource): self.putChild('startup-assets', File(self._startup_folder)) self.putChild('public-assets', File(self._public_folder)) - with open(os.path.join(self._startup_folder, 'Interstitial.html')) as f: + with open(pkg_resources.resource_filename('templates', 'Interstitial.html')) as f: self.interstitial = f.read() def getChild(self, path, request): diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 375f27f6..e6a25e00 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -15,6 +15,7 @@ # along with Pixelated. If not, see . import json import os +import pkg_resources from pixelated.resources.users import UsersResource import pixelated @@ -50,9 +51,8 @@ class RootResource(BaseResource): self._assets_folder = self._get_assets_folder() self._startup_assets_folder = self._get_startup_folder() self._static_folder = static_folder - self._html_template = open(os.path.join(templates_folder, 'index.html')).read() self._services_factory = services_factory - with open(os.path.join(self._startup_assets_folder, 'Interstitial.html')) as f: + with open(pkg_resources.resource_filename('templates', 'Interstitial.html')) as f: self.interstitial = f.read() self._redirect_to_login_resource = Redirect('login') self._inbox_resource = InboxResource(services_factory) @@ -60,7 +60,7 @@ class RootResource(BaseResource): def _startup_mode(self): self.putChildProtected('assets', File(self._assets_folder)) - self.putChildPublic('startup-assets', File(self._startup_assets_folder)) + self.putChildPublic('startup-assets', File(pkg_resources.resource_filename('templates', '.'))) self.putChildPublic('static', File(self._static_folder)) self._mode = MODE_STARTUP logger.debug('Root in STARTUP mode. %s' % self) -- cgit v1.2.3 From ed69fa3b7bf0b543b6c5d3f41504965a1b085808 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Mon, 5 Dec 2016 10:39:10 +0100 Subject: use static instead of {startup,public}-assets --- service/pixelated/resources/login_resource.py | 20 -------------------- service/pixelated/resources/root_resource.py | 13 ------------- 2 files changed, 33 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index 2ca85af9..4318752e 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -35,22 +35,6 @@ from twisted.web.template import Element, XMLFile, renderElement, renderer log = Logger() -def _get_startup_folder(): - path = os.path.dirname(os.path.abspath(__file__)) - return os.path.join(path, '..', 'assets') - - -def _get_public_folder(): - static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "public")) - # this is a workaround for packaging - if not os.path.exists(static_folder): - static_folder = os.path.abspath( - os.path.join(os.path.abspath(__file__), "..", "..", "..", "..", "web-ui", "public")) - if not os.path.exists(static_folder): - static_folder = os.path.join('/', 'usr', 'share', 'pixelated-user-agent') - return static_folder - - def _get_static_folder(): static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "public")) # this is a workaround for packaging @@ -124,15 +108,11 @@ class LoginResource(BaseResource): def __init__(self, services_factory, provider=None, disclaimer_banner=None, authenticator=None): BaseResource.__init__(self, services_factory) self._static_folder = _get_static_folder() - self._public_folder = _get_public_folder() - self._startup_folder = _get_startup_folder() self._disclaimer_banner = disclaimer_banner self._provider = provider self._authenticator = authenticator or Authenticator(provider) self._bootstrap_user_services = BootstrapUserServices(services_factory, provider) - self.putChild('startup-assets', File(self._startup_folder)) - self.putChild('public-assets', File(self._public_folder)) with open(pkg_resources.resource_filename('templates', 'Interstitial.html')) as f: self.interstitial = f.read() diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index e6a25e00..8253a5c1 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -48,8 +48,6 @@ class RootResource(BaseResource): def __init__(self, services_factory, templates_folder, static_folder, public=False): BaseResource.__init__(self, services_factory) self._public = public - self._assets_folder = self._get_assets_folder() - self._startup_assets_folder = self._get_startup_folder() self._static_folder = static_folder self._services_factory = services_factory with open(pkg_resources.resource_filename('templates', 'Interstitial.html')) as f: @@ -59,8 +57,6 @@ class RootResource(BaseResource): self._startup_mode() def _startup_mode(self): - self.putChildProtected('assets', File(self._assets_folder)) - self.putChildPublic('startup-assets', File(pkg_resources.resource_filename('templates', '.'))) self.putChildPublic('static', File(self._static_folder)) self._mode = MODE_STARTUP logger.debug('Root in STARTUP mode. %s' % self) @@ -120,12 +116,3 @@ class RootResource(BaseResource): self._inbox_resource.initialize() self._mode = MODE_RUNNING logger.debug('Root in RUNNING mode. %s' % self) - - def _get_assets_folder(self): - pixelated_path = os.path.dirname(os.path.abspath(pixelated.__file__)) - return os.path.join(pixelated_path, '..', '..', 'web-ui', 'public') - - # TODO: use the public folder for this - def _get_startup_folder(self): - path = os.path.dirname(os.path.abspath(__file__)) - return os.path.join(path, '..', 'assets') -- cgit v1.2.3 From ae871e84f6de213f01299f2754fb2e68d4a3afe2 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Mon, 5 Dec 2016 10:56:24 +0100 Subject: remove templates folder from root resource parameters --- service/pixelated/resources/root_resource.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 8253a5c1..5cc93dbe 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -45,7 +45,7 @@ logger = Logger() class RootResource(BaseResource): - def __init__(self, services_factory, templates_folder, static_folder, public=False): + def __init__(self, services_factory, static_folder, public=False): BaseResource.__init__(self, services_factory) self._public = public self._static_folder = static_folder -- cgit v1.2.3 From 3303510d3dabc4c1efdf39c52db026229d909490 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Mon, 5 Dec 2016 17:13:13 +0100 Subject: no difference between dev and prod static files --- service/pixelated/resources/inbox_resource.py | 8 ++------ service/pixelated/resources/login_resource.py | 12 ------------ 2 files changed, 2 insertions(+), 18 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/inbox_resource.py b/service/pixelated/resources/inbox_resource.py index 13d1f298..d0096efe 100644 --- a/service/pixelated/resources/inbox_resource.py +++ b/service/pixelated/resources/inbox_resource.py @@ -35,8 +35,8 @@ class InboxResource(BaseResource): def __init__(self, services_factory): BaseResource.__init__(self, services_factory) - self._not_quite_the_templates_folder = self._get_not_quite_the_templates_folder() - self._html_template = open(os.path.join(self._not_quite_the_templates_folder, 'index.html')).read() + with open(pkg_resources.resource_filename('templates', 'index.html')) as f: + self._html_template = f.read() with open(pkg_resources.resource_filename('templates', 'Interstitial.html')) as f: self.interstitial = f.read() self._mode = MODE_STARTUP @@ -44,10 +44,6 @@ class InboxResource(BaseResource): def initialize(self): self._mode = MODE_RUNNING - def _get_not_quite_the_templates_folder(self): - path = os.path.dirname(os.path.abspath(pixelated.__file__)) - return os.path.join(path, '..', '..', 'web-ui', 'public') - def _is_starting(self): return self._mode == MODE_STARTUP diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index 4318752e..5838003a 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -35,17 +35,6 @@ from twisted.web.template import Element, XMLFile, renderElement, renderer log = Logger() -def _get_static_folder(): - static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "public")) - # this is a workaround for packaging - if not os.path.exists(static_folder): - static_folder = os.path.abspath( - os.path.join(os.path.abspath(__file__), "..", "..", "..", "..", "web-ui", "public")) - if not os.path.exists(static_folder): - static_folder = os.path.join('/', 'usr', 'share', 'pixelated-user-agent') - return static_folder - - def parse_accept_language(all_headers): accepted_languages = ['pt-BR', 'en-US'] languages = all_headers.get('accept-language', '').split(';')[0] @@ -107,7 +96,6 @@ class LoginResource(BaseResource): def __init__(self, services_factory, provider=None, disclaimer_banner=None, authenticator=None): BaseResource.__init__(self, services_factory) - self._static_folder = _get_static_folder() self._disclaimer_banner = disclaimer_banner self._provider = provider self._authenticator = authenticator or Authenticator(provider) -- cgit v1.2.3 From 206423b83b910308bd9c314af03cf82e9a821974 Mon Sep 17 00:00:00 2001 From: Roald de Vries Date: Tue, 6 Dec 2016 11:55:52 +0100 Subject: remove some TODO's --- service/pixelated/resources/auth.py | 1 - 1 file changed, 1 deletion(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/auth.py b/service/pixelated/resources/auth.py index a2054f18..38045277 100644 --- a/service/pixelated/resources/auth.py +++ b/service/pixelated/resources/auth.py @@ -103,7 +103,6 @@ class PixelatedAuthSessionWrapper(object): def _login(self, credentials, request): def loginSucceeded(args): interface, avatar, logout = args - # TODO: make sandbox public return avatar def loginFailed(result): -- cgit v1.2.3 From eaf2019b6e977d1191e0ee12f694a02bb9612f83 Mon Sep 17 00:00:00 2001 From: Zara Gebru Date: Tue, 6 Dec 2016 15:46:33 +0100 Subject: clean up parameters of authsessionwrapper --- service/pixelated/resources/auth.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'service/pixelated/resources') diff --git a/service/pixelated/resources/auth.py b/service/pixelated/resources/auth.py index 38045277..057eb053 100644 --- a/service/pixelated/resources/auth.py +++ b/service/pixelated/resources/auth.py @@ -83,11 +83,9 @@ class PixelatedAuthSessionWrapper(object): isLeaf = False - def __init__(self, portal, root_resource, anonymous_resource, credentialFactories=[]): + def __init__(self, portal, credentialFactories=[]): self._portal = portal self._credentialFactories = credentialFactories - self._root_resource = root_resource - self._anonymous_resource = anonymous_resource def render(self, request): raise UnsupportedMethod(()) -- cgit v1.2.3