You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

261 lines
8.3 KiB

10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
  1. import uuid
  2. from django.contrib import messages
  3. from django.contrib.auth import login as auth_login
  4. from django.contrib.auth import logout as auth_logout
  5. from django.contrib.auth import authenticate
  6. from django.contrib.auth.decorators import login_required
  7. from django.contrib.auth.hashers import check_password
  8. from django.contrib.auth.models import User
  9. from django.core import signing
  10. from django.http import HttpResponseForbidden, HttpResponseBadRequest
  11. from django.shortcuts import redirect, render
  12. from hc.accounts.forms import (EmailPasswordForm, InviteTeamMemberForm,
  13. RemoveTeamMemberForm, ReportSettingsForm,
  14. SetPasswordForm, TeamNameForm)
  15. from hc.accounts.models import Profile, Member
  16. from hc.api.models import Channel, Check
  17. def _make_user(email):
  18. username = str(uuid.uuid4())[:30]
  19. user = User(username=username, email=email)
  20. user.set_unusable_password()
  21. user.save()
  22. profile = Profile(user=user)
  23. profile.save()
  24. channel = Channel()
  25. channel.user = user
  26. channel.kind = "email"
  27. channel.value = email
  28. channel.email_verified = True
  29. channel.save()
  30. return user
  31. def _associate_demo_check(request, user):
  32. if "welcome_code" in request.session:
  33. check = Check.objects.get(code=request.session["welcome_code"])
  34. # Only associate demo check if it doesn't have an owner already.
  35. if check.user is None:
  36. check.user = user
  37. check.save()
  38. check.assign_all_channels()
  39. del request.session["welcome_code"]
  40. def login(request):
  41. bad_credentials = False
  42. if request.method == 'POST':
  43. form = EmailPasswordForm(request.POST)
  44. if form.is_valid():
  45. email = form.cleaned_data["email"]
  46. password = form.cleaned_data["password"]
  47. if len(password):
  48. user = authenticate(username=email, password=password)
  49. if user is not None and user.is_active:
  50. auth_login(request, user)
  51. return redirect("hc-checks")
  52. bad_credentials = True
  53. else:
  54. try:
  55. user = User.objects.get(email=email)
  56. except User.DoesNotExist:
  57. user = _make_user(email)
  58. _associate_demo_check(request, user)
  59. user.profile.send_instant_login_link()
  60. return redirect("hc-login-link-sent")
  61. else:
  62. form = EmailPasswordForm()
  63. bad_link = request.session.pop("bad_link", None)
  64. ctx = {
  65. "form": form,
  66. "bad_credentials": bad_credentials,
  67. "bad_link": bad_link
  68. }
  69. return render(request, "accounts/login.html", ctx)
  70. def logout(request):
  71. auth_logout(request)
  72. return redirect("hc-index")
  73. def login_link_sent(request):
  74. return render(request, "accounts/login_link_sent.html")
  75. def set_password_link_sent(request):
  76. return render(request, "accounts/set_password_link_sent.html")
  77. def check_token(request, username, token):
  78. if request.user.is_authenticated() and request.user.username == username:
  79. # User is already logged in
  80. return redirect("hc-checks")
  81. user = authenticate(username=username, token=token)
  82. if user is not None and user.is_active:
  83. # This should get rid of "welcome_code" in session
  84. request.session.flush()
  85. user.profile.token = ""
  86. user.profile.save()
  87. auth_login(request, user)
  88. return redirect("hc-checks")
  89. request.session["bad_link"] = True
  90. return redirect("hc-login")
  91. @login_required
  92. def profile(request):
  93. profile = request.user.profile
  94. # Switch user back to its default team
  95. if profile.current_team_id != profile.id:
  96. request.team = profile
  97. profile.current_team_id = profile.id
  98. profile.save()
  99. show_api_key = False
  100. if request.method == "POST":
  101. if "set_password" in request.POST:
  102. profile.send_set_password_link()
  103. return redirect("hc-set-password-link-sent")
  104. elif "create_api_key" in request.POST:
  105. profile.set_api_key()
  106. show_api_key = True
  107. messages.info(request, "The API key has been created!")
  108. elif "revoke_api_key" in request.POST:
  109. profile.api_key = ""
  110. profile.save()
  111. messages.info(request, "The API key has been revoked!")
  112. elif "show_api_key" in request.POST:
  113. show_api_key = True
  114. elif "update_reports_allowed" in request.POST:
  115. form = ReportSettingsForm(request.POST)
  116. if form.is_valid():
  117. profile.reports_allowed = form.cleaned_data["reports_allowed"]
  118. profile.save()
  119. messages.info(request, "Your settings have been updated!")
  120. elif "invite_team_member" in request.POST:
  121. if not profile.team_access_allowed:
  122. return HttpResponseForbidden()
  123. form = InviteTeamMemberForm(request.POST)
  124. if form.is_valid():
  125. email = form.cleaned_data["email"]
  126. try:
  127. user = User.objects.get(email=email)
  128. except User.DoesNotExist:
  129. user = _make_user(email)
  130. profile.invite(user)
  131. messages.info(request, "Invitation to %s sent!" % email)
  132. elif "remove_team_member" in request.POST:
  133. form = RemoveTeamMemberForm(request.POST)
  134. if form.is_valid():
  135. email = form.cleaned_data["email"]
  136. farewell_user = User.objects.get(email=email)
  137. farewell_user.profile.current_team = None
  138. farewell_user.profile.save()
  139. Member.objects.filter(team=profile,
  140. user=farewell_user).delete()
  141. messages.info(request, "%s removed from team!" % email)
  142. elif "set_team_name" in request.POST:
  143. if not profile.team_access_allowed:
  144. return HttpResponseForbidden()
  145. form = TeamNameForm(request.POST)
  146. if form.is_valid():
  147. profile.team_name = form.cleaned_data["team_name"]
  148. profile.save()
  149. messages.info(request, "Team Name updated!")
  150. ctx = {
  151. "profile": profile,
  152. "show_api_key": show_api_key
  153. }
  154. return render(request, "accounts/profile.html", ctx)
  155. @login_required
  156. def set_password(request, token):
  157. profile = request.user.profile
  158. if not check_password(token, profile.token):
  159. return HttpResponseBadRequest()
  160. if request.method == "POST":
  161. form = SetPasswordForm(request.POST)
  162. if form.is_valid():
  163. password = form.cleaned_data["password"]
  164. request.user.set_password(password)
  165. request.user.save()
  166. profile.token = ""
  167. profile.save()
  168. # Setting a password logs the user out, so here we
  169. # log them back in.
  170. u = authenticate(username=request.user.email, password=password)
  171. auth_login(request, u)
  172. messages.info(request, "Your password has been set!")
  173. return redirect("hc-profile")
  174. return render(request, "accounts/set_password.html", {})
  175. def unsubscribe_reports(request, username):
  176. try:
  177. signing.Signer().unsign(request.GET.get("token"))
  178. except signing.BadSignature:
  179. return HttpResponseBadRequest()
  180. user = User.objects.get(username=username)
  181. user.profile.reports_allowed = False
  182. user.profile.save()
  183. return render(request, "accounts/unsubscribed.html")
  184. def switch_team(request, target_username):
  185. other_user = User.objects.get(username=target_username)
  186. # The rules:
  187. # Superuser can switch to any team.
  188. access_ok = request.user.is_superuser
  189. # Users can switch to teams they are members of.
  190. if not access_ok and other_user.id == request.user.id:
  191. access_ok = True
  192. # Users can switch to their own teams.
  193. if not access_ok:
  194. for membership in request.user.member_set.all():
  195. if membership.team.user.id == other_user.id:
  196. access_ok = True
  197. break
  198. if not access_ok:
  199. return HttpResponseForbidden()
  200. request.user.profile.current_team = other_user.profile
  201. request.user.profile.save()
  202. return redirect("hc-checks")