summaryrefslogtreecommitdiff
path: root/service/pixelated/resources/root_resource.py
diff options
context:
space:
mode:
Diffstat (limited to 'service/pixelated/resources/root_resource.py')
-rw-r--r--service/pixelated/resources/root_resource.py120
1 files changed, 45 insertions, 75 deletions
diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py
index 8df76c70..5cc93dbe 100644
--- a/service/pixelated/resources/root_resource.py
+++ b/service/pixelated/resources/root_resource.py
@@ -13,12 +13,12 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
-import hashlib
import json
import os
-from string import Template
+import pkg_resources
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
@@ -33,43 +33,42 @@ 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.web.util import Redirect
from twisted.logger import Logger
-log = Logger()
-
-
-CSRF_TOKEN_LENGTH = 32
-
-MODE_STARTUP = 1
-MODE_RUNNING = 2
+logger = Logger()
class RootResource(BaseResource):
- def __init__(self, services_factory):
+
+ def __init__(self, services_factory, static_folder, public=False):
BaseResource.__init__(self, services_factory)
- 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._public = public
+ self._static_folder = static_folder
self._services_factory = services_factory
- self._child_resources = ChildResourcesMap()
- 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)
self._startup_mode()
def _startup_mode(self):
- self.putChild('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)
- def getChild(self, path, request):
+ def getChildWithDefault(self, path, request):
+ self._add_csrf_cookie(request)
if path == '':
- return self
+ 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):
- return self._child_resources.get(path)
+ return BaseResource.getChildWithDefault(self, path, request)
return UnAuthorizedResource()
def _is_xsrf_valid(self, request):
@@ -78,6 +77,7 @@ class RootResource(BaseResource):
return True
xsrf_token = request.getCookie('XSRF-TOKEN')
+ logger.debug('CSRF token: %s' % xsrf_token)
ajax_request = (request.getHeader('x-requested-with') == 'XMLHttpRequest')
if ajax_request:
@@ -87,62 +87,32 @@ class RootResource(BaseResource):
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 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._mode = MODE_RUNNING
-
- def _get_startup_folder(self):
- path = os.path.dirname(os.path.abspath(__file__))
- return os.path.join(path, '..', 'assets')
+ def putChildPublic(self, path, resource):
+ return BaseResource.putChild(self, path, resource)
- 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
+ def putChildProtected(self, path, resource):
+ return BaseResource.putChild(self, path, UnAuthorizedResource() if self._public else resource)
- def _is_starting(self):
- return self._mode == MODE_STARTUP
+ 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 _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()
+ def initialize(self, provider=None, disclaimer_banner=None, authenticator=None):
+ 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))
+ 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.putChildPublic(LogoutResource.BASE_URL, LogoutResource(self._services_factory))
+
+ self._inbox_resource.initialize()
+ self._mode = MODE_RUNNING
+ logger.debug('Root in RUNNING mode. %s' % self)