user.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. from django.contrib.auth import get_user_model
  2. from django.db import IntegrityError, transaction
  3. from django.utils import timezone
  4. from django.utils.translation import gettext_lazy as _
  5. from ..users.setupnewuser import setup_new_user
  6. from .exceptions import OAuth2UserDataValidationError, OAuth2UserIdNotProvidedError
  7. from .models import Subject
  8. from .validation import validate_user_data
  9. User = get_user_model()
  10. def get_user_from_data(request, user_data):
  11. if not user_data["id"]:
  12. raise OAuth2UserIdNotProvidedError()
  13. user_data["id"] = str(user_data["id"])
  14. user = get_user_by_subject(user_data["id"])
  15. if not user and user_data["email"]:
  16. user = get_user_by_email(user_data["id"], user_data["email"])
  17. created = not bool(user)
  18. cleaned_data = validate_user_data(request, user, user_data)
  19. try:
  20. with transaction.atomic():
  21. if not user:
  22. user = create_new_user(request, cleaned_data)
  23. else:
  24. update_existing_user(user, cleaned_data)
  25. except IntegrityError as error:
  26. raise_validation_error_from_integrity_error(error)
  27. return user, created
  28. def get_user_by_subject(user_id):
  29. try:
  30. subject = Subject.objects.select_related("user", "user__ban_cache").get(
  31. sub=user_id
  32. )
  33. subject.last_used_on = timezone.now()
  34. subject.save(update_fields=["last_used_on"])
  35. return subject.user
  36. except Subject.DoesNotExist:
  37. return None
  38. def get_user_by_email(user_id, user_email):
  39. try:
  40. user = User.objects.get_by_email(user_email)
  41. Subject.objects.create(sub=user_id, user=user)
  42. except User.DoesNotExist:
  43. return None
  44. def create_new_user(request, user_data):
  45. activation_kwargs = {}
  46. if request.settings.account_activation == "admin":
  47. activation_kwargs = {"requires_activation": User.ACTIVATION_ADMIN}
  48. user = User.objects.create_user(
  49. user_data["name"],
  50. user_data["email"],
  51. joined_from_ip=request.user_ip,
  52. **activation_kwargs,
  53. )
  54. setup_new_user(request.settings, user, avatar_url=user_data["avatar"])
  55. Subject.objects.create(sub=user_data["id"], user=user)
  56. return user
  57. def update_existing_user(user, user_data):
  58. save_changes = False
  59. if user.username != user_data["name"]:
  60. user.set_username(user_data["name"])
  61. save_changes = True
  62. if user.email != user_data["email"]:
  63. user.set_email(user_data["email"])
  64. save_changes = True
  65. if save_changes:
  66. user.save()
  67. def raise_validation_error_from_integrity_error(error):
  68. error_str = str(error)
  69. if "misago_users_user_email_hash_key" in error_str:
  70. raise OAuth2UserDataValidationError(
  71. error_list=[_("This e-mail address is not available.")]
  72. )
  73. if "misago_users_user_slug_key" in error_str:
  74. raise OAuth2UserDataValidationError(
  75. error_list=[_("This username is not available.")]
  76. )