Skip to content

Commit 4370a39

Browse files
author
Stefan Majoor
committed
Make binder compatible with django-hijack > 3
1 parent c8a8030 commit 4370a39

File tree

2 files changed

+58
-15
lines changed

2 files changed

+58
-15
lines changed

binder/plugins/views/userview.py

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,44 +38,87 @@ def respond_with_user(self, request, user_id):
3838
class MasqueradeMixin(UserBaseMixin):
3939
__metaclass__ = ABCMeta
4040

41+
def _maquerade_legacy(self, request, user_to_masquerade_as):
42+
"""
43+
This is to only used for django <=4, django-hijack <= 2
44+
"""
45+
from hijack.helpers import login_user
46+
login_user(request, user_to_masquerade_as) # Ignore returned redirect response object
47+
return self.respond_with_user(request, user_to_masquerade_as.id)
48+
4149
@detail_route(name='masquerade')
4250
@no_scoping_required()
4351
def masquerade(self, request, pk=None):
44-
from hijack.helpers import login_user
52+
self._require_model_perm('masquerade', request)
4553

4654
if request.method != 'POST':
4755
raise BinderMethodNotAllowed()
4856

4957
try:
50-
user = self.model._default_manager.get(pk=pk)
58+
user_to_masquerade_as = self.get_queryset(request).get(pk=pk)
5159
except self.model.DoesNotExist:
5260
raise BinderNotFound()
5361

54-
self._require_model_perm('masquerade', request)
62+
try:
63+
from hijack.views import AcquireUserView
64+
except ImportError:
65+
return self._maquerade_legacy(request, user_to_masquerade_as)
66+
67+
class AcquireUserViewAdapter(AcquireUserView):
68+
"""Simple adapter which makes the django-hijack acquire endpoint compatible with the django-binder-api"""
69+
def get_object(self):
70+
return user_to_masquerade_as
71+
72+
def get_redirect_url(self):
73+
return ''
74+
75+
AcquireUserViewAdapter().post(request)
76+
return self.respond_with_user(request, user_to_masquerade_as.id)
77+
78+
def _end_masquerade(self, request) -> bool:
79+
"""
80+
Ends the masquerade for the user, returns a boolean indicating if this was successfull
81+
"""
82+
try:
83+
from hijack.views import ReleaseUserView
84+
except ImportError:
85+
# Legacy way to do it in django <=4, django-hijack <= 2
86+
from hijack.helpers import release_hijack
87+
try:
88+
release_hijack(request)
89+
return True
90+
except PermissionDenied:
91+
return False
92+
93+
class ReleaseUserViewAdapter(ReleaseUserView):
94+
def get_redirect_url(self):
95+
return ''
96+
97+
try:
98+
ReleaseUserViewAdapter().post(request)
99+
return True
100+
except IndexError:
101+
# Raised by the release user view adapter if you are not hijacked currently.
102+
return False
55103

56-
login_user(request, user) # Ignore returned redirect response object
57-
return self.respond_with_user(request, user.id)
58104

59105
@list_route(name='endmasquerade')
60106
@no_scoping_required()
61107
def endmasquerade(self, request):
62-
from hijack.helpers import release_hijack
63-
64108
if request.method != 'POST':
65109
raise BinderMethodNotAllowed()
66110

67111
self._require_model_perm('unmasquerade', request)
68112

69-
release_hijack(request) # Ignore returned redirect response object
113+
self._end_masquerade(request)
70114
return self.respond_with_user(request, request.user.id)
71115

72116
def _logout(self, request):
73-
from hijack.helpers import release_hijack
74-
# Release masquerade on logout if masquerading
75-
try:
76-
release_hijack(request)
77-
except PermissionDenied: # Means we are not hijacked
78-
super()._logout(request)
117+
if self._end_masquerade(request):
118+
# If we were masqueraded -> that counts as our logout.
119+
return
120+
121+
super()._logout(request)
79122

80123

81124

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
],
4545
extras_require={
4646
'test': [
47-
'django-hijack >= 2.1.10, < 3.0.0',
47+
'django-hijack >= 2.1.10',
4848
(
4949
'mysqlclient >= 1.3.12'
5050
if os.environ.get('BINDER_TEST_MYSQL', '0') == '1' else

0 commit comments

Comments
 (0)