views.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. from __future__ import unicode_literals
  2. from django.contrib import messages
  3. from django.contrib.auth import login as auth_login, logout as auth_logout, update_session_auth_hash
  4. from django.contrib.auth.decorators import login_required
  5. from django.contrib.auth.mixins import LoginRequiredMixin
  6. from django.http import HttpResponseRedirect
  7. from django.shortcuts import get_object_or_404, redirect, render
  8. from django.urls import reverse
  9. from django.utils.decorators import method_decorator
  10. from django.utils.http import is_safe_url
  11. from django.views.generic import View
  12. from secrets.forms import UserKeyForm
  13. from secrets.models import SessionKey, UserKey
  14. from utilities.forms import ConfirmationForm
  15. from .forms import LoginForm, PasswordChangeForm, TokenForm
  16. from .models import Token
  17. #
  18. # Login/logout
  19. #
  20. class LoginView(View):
  21. template_name = 'login.html'
  22. def get(self, request):
  23. form = LoginForm(request)
  24. return render(request, self.template_name, {
  25. 'form': form,
  26. })
  27. def post(self, request):
  28. form = LoginForm(request, data=request.POST)
  29. if form.is_valid():
  30. # Determine where to direct user after successful login
  31. redirect_to = request.POST.get('next', '')
  32. if not is_safe_url(url=redirect_to, host=request.get_host()):
  33. redirect_to = reverse('home')
  34. # Authenticate user
  35. auth_login(request, form.get_user())
  36. messages.info(request, "Logged in as {}.".format(request.user))
  37. return HttpResponseRedirect(redirect_to)
  38. return render(request, self.template_name, {
  39. 'form': form,
  40. })
  41. class LogoutView(View):
  42. def get(self, request):
  43. # Log out the user
  44. auth_logout(request)
  45. messages.info(request, "You have logged out.")
  46. # Delete session key cookie (if set) upon logout
  47. response = HttpResponseRedirect(reverse('home'))
  48. response.delete_cookie('session_key')
  49. return response
  50. #
  51. # User profiles
  52. #
  53. @method_decorator(login_required, name='dispatch')
  54. class ProfileView(View):
  55. template_name = 'users/profile.html'
  56. def get(self, request):
  57. return render(request, self.template_name, {
  58. 'active_tab': 'profile',
  59. })
  60. @method_decorator(login_required, name='dispatch')
  61. class ChangePasswordView(View):
  62. template_name = 'users/change_password.html'
  63. def get(self, request):
  64. form = PasswordChangeForm(user=request.user)
  65. return render(request, self.template_name, {
  66. 'form': form,
  67. 'active_tab': 'change_password',
  68. })
  69. def post(self, request):
  70. form = PasswordChangeForm(user=request.user, data=request.POST)
  71. if form.is_valid():
  72. form.save()
  73. update_session_auth_hash(request, form.user)
  74. messages.success(request, "Your password has been changed successfully.")
  75. return redirect('user:profile')
  76. return render(request, self.template_name, {
  77. 'form': form,
  78. 'active_tab': 'change_password',
  79. })
  80. @method_decorator(login_required, name='dispatch')
  81. class UserKeyView(View):
  82. template_name = 'users/userkey.html'
  83. def get(self, request):
  84. try:
  85. userkey = UserKey.objects.get(user=request.user)
  86. except UserKey.DoesNotExist:
  87. userkey = None
  88. return render(request, self.template_name, {
  89. 'userkey': userkey,
  90. 'active_tab': 'userkey',
  91. })
  92. class UserKeyEditView(View):
  93. template_name = 'users/userkey_edit.html'
  94. @method_decorator(login_required)
  95. def dispatch(self, request, *args, **kwargs):
  96. try:
  97. self.userkey = UserKey.objects.get(user=request.user)
  98. except UserKey.DoesNotExist:
  99. self.userkey = UserKey(user=request.user)
  100. return super(UserKeyEditView, self).dispatch(request, *args, **kwargs)
  101. def get(self, request):
  102. form = UserKeyForm(instance=self.userkey)
  103. return render(request, self.template_name, {
  104. 'userkey': self.userkey,
  105. 'form': form,
  106. 'active_tab': 'userkey',
  107. })
  108. def post(self, request):
  109. form = UserKeyForm(data=request.POST, instance=self.userkey)
  110. if form.is_valid():
  111. uk = form.save(commit=False)
  112. uk.user = request.user
  113. uk.save()
  114. messages.success(request, "Your user key has been saved.")
  115. return redirect('user:userkey')
  116. return render(request, self.template_name, {
  117. 'userkey': self.userkey,
  118. 'form': form,
  119. 'active_tab': 'userkey',
  120. })
  121. @method_decorator(login_required, name='dispatch')
  122. class SessionKeyDeleteView(LoginRequiredMixin, View):
  123. def get(self, request):
  124. sessionkey = get_object_or_404(SessionKey, userkey__user=request.user)
  125. form = ConfirmationForm()
  126. return render(request, 'users/sessionkey_delete.html', {
  127. 'obj_type': sessionkey._meta.verbose_name,
  128. 'form': form,
  129. 'return_url': reverse('user:userkey'),
  130. })
  131. def post(self, request):
  132. sessionkey = get_object_or_404(SessionKey, userkey__user=request.user)
  133. form = ConfirmationForm(request.POST)
  134. if form.is_valid():
  135. # Delete session key
  136. sessionkey.delete()
  137. messages.success(request, "Session key deleted")
  138. # Delete cookie
  139. response = redirect('user:userkey')
  140. response.delete_cookie('session_key')
  141. return response
  142. return render(request, 'users/sessionkey_delete.html', {
  143. 'obj_type': sessionkey._meta.verbose_name,
  144. 'form': form,
  145. 'return_url': reverse('user:userkey'),
  146. })
  147. @method_decorator(login_required, name='dispatch')
  148. class RecentActivityView(View):
  149. template_name = 'users/recent_activity.html'
  150. def get(self, request):
  151. return render(request, self.template_name, {
  152. 'recent_activity': request.user.actions.all()[:50],
  153. 'active_tab': 'recent_activity',
  154. })
  155. #
  156. # API tokens
  157. #
  158. class TokenListView(LoginRequiredMixin, View):
  159. def get(self, request):
  160. tokens = Token.objects.filter(user=request.user)
  161. return render(request, 'users/api_tokens.html', {
  162. 'tokens': tokens,
  163. 'active_tab': 'api_tokens',
  164. })
  165. class TokenEditView(LoginRequiredMixin, View):
  166. def get(self, request, pk=None):
  167. if pk is not None:
  168. token = get_object_or_404(Token.objects.filter(user=request.user), pk=pk)
  169. else:
  170. token = Token(user=request.user)
  171. form = TokenForm(instance=token)
  172. return render(request, 'utilities/obj_edit.html', {
  173. 'obj': token,
  174. 'obj_type': token._meta.verbose_name,
  175. 'form': form,
  176. 'return_url': reverse('user:token_list'),
  177. })
  178. def post(self, request, pk=None):
  179. if pk is not None:
  180. token = get_object_or_404(Token.objects.filter(user=request.user), pk=pk)
  181. form = TokenForm(request.POST, instance=token)
  182. else:
  183. token = Token()
  184. form = TokenForm(request.POST)
  185. if form.is_valid():
  186. token = form.save(commit=False)
  187. token.user = request.user
  188. token.save()
  189. msg = "Modified token {}".format(token) if pk else "Created token {}".format(token)
  190. messages.success(request, msg)
  191. if '_addanother' in request.POST:
  192. return redirect(request.path)
  193. else:
  194. return redirect('user:token_list')
  195. return render(request, 'utilities/obj_edit.html', {
  196. 'obj': token,
  197. 'obj_type': token._meta.verbose_name,
  198. 'form': form,
  199. 'return_url': reverse('user:token_list'),
  200. })
  201. class TokenDeleteView(LoginRequiredMixin, View):
  202. def get(self, request, pk):
  203. token = get_object_or_404(Token.objects.filter(user=request.user), pk=pk)
  204. initial_data = {
  205. 'return_url': reverse('user:token_list'),
  206. }
  207. form = ConfirmationForm(initial=initial_data)
  208. return render(request, 'utilities/obj_delete.html', {
  209. 'obj': token,
  210. 'obj_type': token._meta.verbose_name,
  211. 'form': form,
  212. 'return_url': reverse('user:token_list'),
  213. })
  214. def post(self, request, pk):
  215. token = get_object_or_404(Token.objects.filter(user=request.user), pk=pk)
  216. form = ConfirmationForm(request.POST)
  217. if form.is_valid():
  218. token.delete()
  219. messages.success(request, "Token deleted")
  220. return redirect('user:token_list')
  221. return render(request, 'utilities/obj_delete.html', {
  222. 'obj': token,
  223. 'obj_type': token._meta.verbose_name,
  224. 'form': form,
  225. 'return_url': reverse('user:token_list'),
  226. })