[feature] allow to pass a static_folder to RootResource
[pixelated-user-agent.git] / service / pixelated / resources / __init__.py
1 #
2 # Copyright (c) 2014 ThoughtWorks, Inc.
3 #
4 # Pixelated is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # Pixelated is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
16
17 import json
18 import os
19
20 from twisted.web.http import UNAUTHORIZED
21 from twisted.web.resource import Resource
22 from twisted.logger import Logger
23
24 from pixelated.resources.session import IPixelatedSession
25
26 from twisted.web.http import INTERNAL_SERVER_ERROR, SERVICE_UNAVAILABLE
27
28 log = Logger()
29
30
31 class SetEncoder(json.JSONEncoder):
32     def default(self, obj):
33         if isinstance(obj, set):
34             return list(obj)
35         return super(SetEncoder, self).default(obj)
36
37
38 def respond_json(entity, request, status_code=200):
39     json_response = json.dumps(entity, cls=SetEncoder)
40     request.responseHeaders.setRawHeaders(b"content-type", [b"application/json"])
41     request.code = status_code
42     return json_response
43
44
45 def respond_json_deferred(entity, request, status_code=200):
46     json_response = json.dumps(entity, cls=SetEncoder)
47     request.responseHeaders.setRawHeaders(b"content-type", [b"application/json"])
48     request.code = status_code
49     request.write(json_response)
50     request.finish()
51
52
53 def handle_error_deferred(e, request):
54     log.error(e)
55     request.setResponseCode(INTERNAL_SERVER_ERROR)
56     request.write('Something went wrong!')
57     request.finish()
58
59
60 def get_protected_static_folder(static_folder=None):
61     static = static_folder or _get_static_folder()
62     return os.path.join(static, 'protected')
63
64
65 def get_public_static_folder(static_folder=None):
66     static = static_folder or _get_static_folder()
67     return os.path.join(static, 'public')
68
69
70 def _get_static_folder():
71     static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "..", "web-ui", "dist"))
72     if not os.path.exists(static_folder):
73         static_folder = os.path.join('/', 'usr', 'share', 'pixelated-user-agent')
74     return static_folder
75
76
77 class BaseResource(Resource):
78
79     def __init__(self, services_factory):
80         Resource.__init__(self)
81         self._services_factory = services_factory
82
83     def _get_user_id_from_request(self, request):
84         if self._services_factory.mode.is_single_user:
85             return None  # it doesn't matter
86         session = self.get_session(request)
87         if session.is_logged_in():
88             return session.user_uuid
89         raise ValueError('Not logged in')
90
91     def is_logged_in(self, request):
92         session = self.get_session(request)
93         return session.is_logged_in() and self._services_factory.has_session(session.user_uuid)
94
95     def get_session(self, request):
96         return IPixelatedSession(request.getSession())
97
98     def is_admin(self, request):
99         services = self._services(request)
100         return services._leap_session.user_auth.is_admin()
101
102     def _services(self, request):
103         user_id = self._get_user_id_from_request(request)
104         return self._services_factory.services(user_id)
105
106     def _service(self, request, attribute):
107         return getattr(self._services(request), attribute)
108
109     def keymanager(self, request):
110         return self._service(request, 'keymanager')
111
112     def mail_service(self, request):
113         return self._service(request, 'mail_service')
114
115     def search_engine(self, request):
116         return self._service(request, 'search_engine')
117
118     def draft_service(self, request):
119         return self._service(request, 'draft_service')
120
121     def feedback_service(self, request):
122         return self._service(request, 'feedback_service')
123
124     def soledad(self, request):
125         return self._service(request, '_leap_session').soledad
126
127
128 class UnAuthorizedResource(Resource):
129
130     def __init__(self):
131         Resource.__init__(self)
132
133     def render_GET(self, request):
134         request.setResponseCode(UNAUTHORIZED)
135         return "Unauthorized!"
136
137     def render_POST(self, request):
138         request.setResponseCode(UNAUTHORIZED)
139         return "Unauthorized!"
140
141
142 class UnavailableResource(Resource):
143     def __init__(self):
144         Resource.__init__(self)
145
146     def render(self, request):
147         request.setResponseCode(SERVICE_UNAVAILABLE)
148         return "Service Unavailable"