summaryrefslogtreecommitdiff
path: root/service/pixelated/resources/login_resource.py
blob: b0e8ac3be78cd872e85d15525180ab1059dd3ce3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#
# 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 <http://www.gnu.org/licenses/>.

import logging
import os
from string import Template

from twisted.cred import credentials
from twisted.internet import defer
from twisted.web.resource import IResource
from twisted.web.server import NOT_DONE_YET
from twisted.web.static import File

from pixelated.resources import BaseResource, UnAuthorizedResource

log = logging.getLogger(__name__)


class LoginResource(BaseResource):

    def __init__(self, services_factory, portal=None):
        BaseResource.__init__(self, services_factory)
        self._static_folder = self._get_static_folder()
        self._startup_folder = self._get_startup_folder()
        self._html_template = open(os.path.join(self._startup_folder, 'login.html')).read()
        self._portal = portal
        self.putChild('startup-assets', File(self._startup_folder))

    def set_portal(self, portal):
        self._portal = portal

    def getChild(self, path, request):
        if path == '':
            return self
        if path == 'login':
            return self
        return UnAuthorizedResource()

    def render_GET(self, request):
        response = Template(self._html_template).safe_substitute()
        return str(response)

    def render_POST(self, request):

        def render_response(response):
            request.redirect("/")
            request.finish()

        def render_error(error):
            login_form = self.render_GET(request)
            request.status = 500
            request.write('We got an error:\n')
            request.write(str(error))
            request.write(login_form)
            request.finish()

        d = self._handle_login(request)
        d.addCallbacks(render_response, render_error)

        return NOT_DONE_YET

    @defer.inlineCallbacks
    def _handle_login(self, request):
        if self.is_logged_in(request):
            defer.succeed(None)
            return
        username = request.args['username'][0]
        password = request.args['password'][0]
        creds = credentials.UsernamePassword(username, password)

        iface, leap_user, logout = yield self._portal.login(creds, None, IResource)

        # we should really check whether the response is anonymous

        yield leap_user.start_services(self._services_factory)
        leap_user.init_http_session(request)

        log.info('about to redirect to home page')

    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