2 # Copyright (C) 2014, 2015, 2018 Jessica Tallon & Matt Molyneaux
4 # This file is part of Inboxen.
6 # Inboxen is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Affero General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # Inboxen is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Affero General Public License for more details.
16 # You should have received a copy of the GNU Affero General Public License
17 # along with Inboxen. If not, see <http://www.gnu.org/licenses/>.
24 from django
import test
25 from django
.contrib
.auth
.models
import AnonymousUser
26 from django
.contrib
.messages
.storage
.session
import SessionStorage
27 from django
.contrib
.sessions
.middleware
import SessionMiddleware
28 from django
.http
import HttpRequest
, HttpResponse
29 from django
.test
.runner
import DiscoverRunner
30 from django
.utils
.crypto
import get_random_string
31 from django_otp
import DEVICE_ID_SESSION_KEY
32 from django_otp
.middleware
import OTPMiddleware
33 from django_otp
.plugins
.otp_static
.models
import StaticDevice
34 from elevate
import settings
as elevate_settings
35 from elevate
.middleware
import ElevateMiddleware
37 _log
= logging
.getLogger(__name__
)
40 class MockRequest(HttpRequest
):
41 """Mock up a request object"""
43 def __init__(self
, user
=None, session_id
=None, has_otp
=False, has_sudo
=False):
44 super(MockRequest
, self
).__init
__()
48 self
.user
= AnonymousUser()
52 session
= SessionMiddleware(lambda x
: x
)
53 self
.session
= session
.SessionStore(session_id
)
54 self
._messages
= SessionStorage(self
)
55 self
.META
= {"REMOTE_ADDR": "127.0.0.1"}
58 ElevateMiddleware(lambda x
: x
)(self
)
64 grant_otp(self
, self
.user
)
65 OTPMiddleware(lambda x
: x
)(self
)
68 # TODO: submit to django-elevate?
69 def grant_sudo(client_or_request
):
70 """Sets a cookie on the test client or request that django-elevate will use"""
71 response
= HttpResponse()
72 token
= get_random_string(elevate_settings
.TOKEN_LENGTH
)
74 response
.set_signed_cookie(
75 elevate_settings
.COOKIE_NAME
,
77 salt
=elevate_settings
.COOKIE_SALT
,
78 max_age
=elevate_settings
.COOKIE_AGE
,
81 path
=elevate_settings
.COOKIE_PATH
,
82 domain
=elevate_settings
.COOKIE_DOMAIN
,
85 if hasattr(client_or_request
, "cookies"):
86 client_or_request
.cookies
[elevate_settings
.COOKIE_NAME
] = response
.cookies
[elevate_settings
.COOKIE_NAME
]
87 elif hasattr(client_or_request
, "COOKIES"):
88 client_or_request
.COOKIES
[elevate_settings
.COOKIE_NAME
] = response
.cookies
[elevate_settings
.COOKIE_NAME
].value
90 raise TypeError("%r has neither cookies nor COOKIES" % client_or_request
)
92 # client.session is a property that returns new objects
93 session
= client_or_request
.session
94 session
[elevate_settings
.COOKIE_NAME
] = token
98 def grant_otp(client_or_request
, user
):
99 """Sets session data for OTP"""
100 device
= StaticDevice
.objects
.get_or_create(user
=user
)[0]
102 # client.session is a property that returns new objects
103 session
= client_or_request
.session
104 session
[DEVICE_ID_SESSION_KEY
] = device
.persistent_id
108 class InboxenTestRunner(DiscoverRunner
):
109 """Test runner for Inboxen"""
110 def setup_test_environment(self
, **kwargs
):
111 self
.is_testing_var_set
= int(os
.getenv('INBOXEN_TESTING', '0')) > 0
112 super(InboxenTestRunner
, self
).setup_test_environment(**kwargs
)
114 def teardown_test_environment(self
, **kwargs
):
115 super(InboxenTestRunner
, self
).teardown_test_environment(**kwargs
)
116 if not self
.is_testing_var_set
:
117 warnings
.warn("You did not set 'INBOXEN_TESTING' in your environment. Test results will be unreliable!")
120 CLIENT_METHODS_TO_MAKE_SECURE
= [
132 class SecureClient(test
.Client
):
133 """Like Client, but changes the deafult "secure" kwargs to True on certain methods"""
134 def __getattribute__(self
, name
):
135 attr
= super(SecureClient
, self
).__getattribute
__(name
)
136 if name
in CLIENT_METHODS_TO_MAKE_SECURE
:
138 def be_secure(*args
, **kwargs
):
139 kwargs
.setdefault("secure", True)
140 return attr(*args
, **kwargs
)
147 class InboxenTestCase(test
.TestCase
):
148 client_class
= SecureClient