pipeline.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. from django.contrib.auth import get_user_model
  2. from django.utils.translation import ugettext as _
  3. from misago.conf import settings
  4. from misago.core.exceptions import SocialAuthFailed, SocialAuthBanned
  5. from misago.users.models import Ban
  6. from misago.users.bans import get_request_ip_ban, get_user_ban
  7. from misago.users.validators import ValidationError, validate_username, validate_email
  8. from .utils import get_social_auth_backend_name, perpare_username
  9. UserModel = get_user_model()
  10. def validate_ip_not_banned(strategy, details, backend, user=None, *args, **kwargs):
  11. """Pipeline step that interrupts pipeline if found user is non-staff and IP banned"""
  12. if not user or user.is_staff:
  13. return None
  14. ban = get_request_ip_ban(strategy.request)
  15. if ban:
  16. hydrated_ban = Ban(
  17. check_type=Ban.IP,
  18. user_message=ban['message'],
  19. expires_on=ban['expires_on'],
  20. )
  21. raise SocialAuthBanned(backend, hydrated_ban)
  22. def validate_user_not_banned(strategy, details, backend, user=None, *args, **kwargs):
  23. """Pipeline step that interrupts pipeline if found user is non-staff and banned"""
  24. if not user or user.is_staff:
  25. return None
  26. user_ban = get_user_ban(user)
  27. if user_ban:
  28. raise SocialAuthBanned(backend, user_ban)
  29. def associate_by_email(strategy, details, backend, user=None, *args, **kwargs):
  30. """If user with e-mail from provider exists in database and is active,
  31. this step authenticates them.
  32. """
  33. if user:
  34. return None
  35. email = details.get('email')
  36. if not email:
  37. return None
  38. try:
  39. user = UserModel.objects.get_by_email(email)
  40. except UserModel.DoesNotExist:
  41. return None
  42. backend_name = get_social_auth_backend_name(backend.name)
  43. if not user.is_active:
  44. raise SocialAuthFailed(
  45. backend,
  46. _(
  47. "The e-mail address associated with your %(backend)s account is "
  48. "not available for use on this site."
  49. ) % {'backend': backend_name}
  50. )
  51. if user.requires_activation_by_admin:
  52. raise SocialAuthFailed(
  53. backend,
  54. _(
  55. "Your account has to be activated by site administrator before you will be able to "
  56. "sign in with %(backend)s."
  57. ) % {'backend': backend_name}
  58. )
  59. return {'user': user, 'is_new': False}
  60. def get_username(strategy, details, backend, user=None, *args, **kwargs):
  61. """Resolve valid username for use in new account"""
  62. if user:
  63. return None
  64. username = perpare_username(details.get('username', ''))
  65. full_name = perpare_username(details.get('full_name', ''))
  66. first_name = perpare_username(details.get('first_name', ''))
  67. last_name = perpare_username(details.get('last_name', ''))
  68. names_to_try = [
  69. username,
  70. first_name,
  71. ]
  72. if username:
  73. names_to_try.append(username)
  74. if first_name:
  75. names_to_try.append(first_name)
  76. if last_name:
  77. # if first name is taken, try first name + first char of last name
  78. names_to_try.append(first_name + last_name[0])
  79. if full_name:
  80. names_to_try.append(full_name)
  81. username_length_max = settings.username_length_max
  82. for name in names_to_try:
  83. if len(name) > username_length_max:
  84. names_to_try.append(name[:username_length_max])
  85. for name in filter(bool, names_to_try):
  86. try:
  87. validate_username(name)
  88. return {'clean_username': name}
  89. except ValidationError:
  90. pass
  91. def create_user(strategy, details, backend, user=None, *args, **kwargs):
  92. """Aggressively attempt to register and sign in new user"""
  93. if user:
  94. return None
  95. email = details.get('email')
  96. username = kwargs.get('clean_username')
  97. if not email or not username:
  98. return None
  99. try:
  100. validate_email(email)
  101. except ValidationError:
  102. return None
  103. user = UserModel.objects.create_user(username, email, set_default_avatar=True)
  104. return {'user': user, 'is_new': True}
  105. def create_user_with_form(strategy, details, backend, user=None, *args, **kwargs):
  106. """Alternatively to create_user lets user confirm account creation before authenticating"""
  107. if user:
  108. return None