diff options
| -rw-r--r-- | osx_setup.sh | 2 | ||||
| -rw-r--r-- | service/pixelated/application.py | 8 | ||||
| -rw-r--r-- | service/pixelated/assets/_login_disclaimer_banner.html | 9 | ||||
| -rw-r--r-- | service/pixelated/assets/login.html | 2 | ||||
| -rw-r--r-- | service/pixelated/config/arguments.py | 1 | ||||
| -rw-r--r-- | service/pixelated/resources/login_resource.py | 30 | ||||
| -rw-r--r-- | service/pixelated/resources/root_resource.py | 4 | ||||
| -rw-r--r-- | service/test/unit/resources/test_login_resource.py | 31 | 
8 files changed, 73 insertions, 14 deletions
| diff --git a/osx_setup.sh b/osx_setup.sh index 26b5b749..a8a37833 100644 --- a/osx_setup.sh +++ b/osx_setup.sh @@ -36,7 +36,7 @@ install_compass  install_npm  #setup backend -brew install python # force brew install even if python is already install +brew install python # force brew install even if python is already installed  export  LDFLAGS=-L/usr/local/opt/openssl/lib  export  LDFLAGS=-L/usr/local/opt/openssl/lib  pip install virtualenv diff --git a/service/pixelated/application.py b/service/pixelated/application.py index b0f2d3fc..c7613fc6 100644 --- a/service/pixelated/application.py +++ b/service/pixelated/application.py @@ -166,24 +166,24 @@ def _start_in_multi_user_mode(args, root_resource, services_factory):      events_server.ensure_server()      config, provider = initialize_leap_provider(args.provider, args.leap_provider_cert, args.leap_provider_cert_fingerprint, args.leap_home) -    protected_resource = set_up_protected_resources(root_resource, provider, services_factory) +    protected_resource = set_up_protected_resources(root_resource, provider, services_factory, banner=args.banner)      start_site(args, protected_resource)      reactor.getThreadPool().adjustPoolsize(5, 15)      return defer.succeed(None) -def set_up_protected_resources(root_resource, provider, services_factory, checker=None): +def set_up_protected_resources(root_resource, provider, services_factory, checker=None, banner=None):      if not checker:          checker = LeapPasswordChecker(provider)      session_checker = SessionChecker(services_factory) -    anonymous_resource = LoginResource(services_factory) +    anonymous_resource = LoginResource(services_factory, disclaimer_banner=banner)      realm = PixelatedRealm(root_resource, anonymous_resource)      _portal = portal.Portal(realm, [checker, session_checker, AllowAnonymousAccess()])      protected_resource = PixelatedAuthSessionWrapper(_portal, root_resource, anonymous_resource, [])      anonymous_resource.set_portal(_portal) -    root_resource.initialize(_portal) +    root_resource.initialize(_portal, disclaimer_banner=banner)      return protected_resource diff --git a/service/pixelated/assets/_login_disclaimer_banner.html b/service/pixelated/assets/_login_disclaimer_banner.html new file mode 100644 index 00000000..dfc63030 --- /dev/null +++ b/service/pixelated/assets/_login_disclaimer_banner.html @@ -0,0 +1,9 @@ +<div> +    <ul class="accounts"> +        <h2>Some disclaimer</h2> +        <li> +            please supply the option --banner with an XML compatible file +            <div>to override this default message</div> +        </li> +    </ul> +</div> diff --git a/service/pixelated/assets/login.html b/service/pixelated/assets/login.html index d59ac4cd..a8585d05 100644 --- a/service/pixelated/assets/login.html +++ b/service/pixelated/assets/login.html @@ -28,7 +28,7 @@          </form>      </div>      <div class="disclaimer"> -        Some disclaimer +        <div t:render="disclaimer"></div>      </div>  </div>  </body> diff --git a/service/pixelated/config/arguments.py b/service/pixelated/config/arguments.py index 6a609b73..abd5d881 100644 --- a/service/pixelated/config/arguments.py +++ b/service/pixelated/config/arguments.py @@ -30,6 +30,7 @@ def parse_user_agent_args():      parser.add_argument('-sc', '--sslcert', metavar='<server.crt>', default=None, help='use specified file as web server\'s SSL certificate (when using the user-agent together with the pixelated-dispatcher)')      parser.add_argument('--multi-user', help='Run user agent in multi user mode', action='store_false', default=True, dest='single_user')      parser.add_argument('-p', '--provider', help='specify a provider for mutli-user mode', metavar='<provider host>', default=None, dest='provider') +    parser.add_argument('--banner', help='banner file to show on login screen')      args = parser.parse_args() diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index 1e1beb48..6f25fbcb 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -49,30 +49,48 @@ def _get_static_folder():      return static_folder +class DisclaimerElement(Element): +    loader = XMLFile(FilePath(os.path.join(_get_startup_folder(), '_login_disclaimer_banner.html'))) + +    def __init__(self, banner): +        super(DisclaimerElement, self).__init__() +        self._set_loader(banner) + +    def _set_loader(self, banner): +        if banner: +            current_path = os.path.dirname(os.path.abspath(__file__)) +            banner_file_path = os.path.join(current_path, "..", "..", "..", banner) +            self.loader = XMLFile(FilePath(banner_file_path)) + +  class LoginWebSite(Element):      loader = XMLFile(FilePath(os.path.join(_get_startup_folder(), 'login.html'))) -    def __init__(self, error_msg=None): +    def __init__(self, error_msg=None, disclaimer_banner_file=None):          super(LoginWebSite, self).__init__()          self._error_msg = error_msg +        self.disclaimer_banner_file = disclaimer_banner_file      @renderer      def error_msg(self, request, tag):          if self._error_msg is not None:              return tag(self._error_msg) -        else: -            return tag('') +        return tag('') + +    @renderer +    def disclaimer(self, request, tag): +        return DisclaimerElement(self.disclaimer_banner_file).render(request)  class LoginResource(BaseResource):      BASE_URL = 'login' -    def __init__(self, services_factory, portal=None): +    def __init__(self, services_factory, portal=None, disclaimer_banner=None):          BaseResource.__init__(self, services_factory)          self._static_folder = _get_static_folder()          self._startup_folder = _get_startup_folder() -        self._html_template = open(os.path.join(self._startup_folder, 'login.html')).read()          self._portal = portal +        self._disclaimer_banner = disclaimer_banner          self.putChild('startup-assets', File(self._startup_folder))      def set_portal(self, portal): @@ -92,7 +110,7 @@ class LoginResource(BaseResource):          return self._render_template(request)      def _render_template(self, request, error_msg=None): -        site = LoginWebSite(error_msg=error_msg) +        site = LoginWebSite(error_msg=error_msg, disclaimer_banner_file=self._disclaimer_banner)          return renderElement(request, site)      def render_POST(self, request): diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 61df0f39..6e619951 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -56,7 +56,7 @@ class RootResource(BaseResource):              return self          return Resource.getChild(self, path, request) -    def initialize(self, portal=None): +    def initialize(self, portal=None, disclaimer_banner=None):          self.putChild('assets', File(self._static_folder))          self.putChild('keys', KeysResource(self._services_factory))          self.putChild(AttachmentsResource.BASE_URL, AttachmentsResource(self._services_factory)) @@ -67,7 +67,7 @@ class RootResource(BaseResource):          self.putChild('mail', MailResource(self._services_factory))          self.putChild('feedback', FeedbackResource(self._services_factory))          self.putChild('user-settings', UserSettingsResource(self._services_factory)) -        self.putChild(LoginResource.BASE_URL, LoginResource(self._services_factory, portal)) +        self.putChild(LoginResource.BASE_URL, LoginResource(self._services_factory, portal, disclaimer_banner=disclaimer_banner))          self.putChild(LogoutResource.BASE_URL, LogoutResource(self._services_factory))          self._mode = MODE_RUNNING diff --git a/service/test/unit/resources/test_login_resource.py b/service/test/unit/resources/test_login_resource.py index bc238ae8..3cd9d3b2 100644 --- a/service/test/unit/resources/test_login_resource.py +++ b/service/test/unit/resources/test_login_resource.py @@ -1,3 +1,5 @@ +import os +  import test.support.mockito  from leap.exceptions import SRPAuthenticationError @@ -58,16 +60,45 @@ class TestLoginResource(unittest.TestCase):              input_username = 'name="username"'              input_password = 'name="password"'              input_submit = 'name="login"' +            default_disclaimer = 'Some disclaimer'              written_response = ''.join(request.written)              self.assertIn(form_action, written_response)              self.assertIn(form_method, written_response)              self.assertIn(input_password, written_response)              self.assertIn(input_submit, written_response)              self.assertIn(input_username, written_response) +            self.assertIn(default_disclaimer, written_response)          d.addCallback(assert_form_rendered)          return d +    def _write(self, filename, content): +        with open(filename, 'w') as disclaimer_file: +            disclaimer_file.write(content) + +    def test_override_login_disclaimer_message(self): +        request = DummyRequest(['']) + +        banner_file_name = 'banner.txt' +        banner_disclaimer_content = '<p>some custom disclaimer</p>' +        self._write(banner_file_name, banner_disclaimer_content) + +        self.resource._disclaimer_banner = 'service/_trial_temp/' + banner_file_name + +        d = self.web.get(request) + +        def assert_custom_disclaimer_rendered(_): +            self.assertEqual(200, request.responseCode) +            written_response = ''.join(request.written) +            self.assertIn(banner_disclaimer_content, written_response) + +        def tear_down(_): +            os.remove(banner_file_name) + +        d.addCallback(assert_custom_disclaimer_rendered) +        d.addCallback(tear_down) +        return d +  class TestLoginPOST(unittest.TestCase):      def setUp(self): | 
