mirror of
https://github.com/pretix/pretix.git
synced 2026-07-19 07:28:37 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 806b4d1cc5 | |||
| 5de7824b66 | |||
| ed432fefad | |||
| c36bf71403 | |||
| fbf0034d04 | |||
| ec4f4f81b4 | |||
| f461f82f36 |
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.2.12 on 2026-07-01 08:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("pretixbase", "0301_reusablemedium_remove_orderposition"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="customerssoprovider",
|
||||
name="allow_convert_to_sso",
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
@@ -73,6 +73,13 @@ class CustomerSSOProvider(LoggedModel):
|
||||
null=False, blank=False,
|
||||
choices=METHODS,
|
||||
)
|
||||
allow_convert_to_sso = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name=_("Convert existing customers to single-sign-on accounts on login"),
|
||||
help_text=_(
|
||||
"If enabled, when an existing customer registered with email and password tries to login through this SSO provider, pretix changes the account to single-sign-on. Otherwise pretix does not allow to log in."
|
||||
),
|
||||
)
|
||||
configuration = models.JSONField()
|
||||
|
||||
def allow_delete(self):
|
||||
|
||||
@@ -1244,7 +1244,7 @@ class SSOProviderForm(I18nModelForm):
|
||||
|
||||
class Meta:
|
||||
model = CustomerSSOProvider
|
||||
fields = ['is_active', 'name', 'button_label', 'method']
|
||||
fields = ['is_active', 'name', 'button_label', 'method', 'allow_convert_to_sso']
|
||||
widgets = {
|
||||
'method': forms.RadioSelect,
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
<legend>{% trans "Customer accounts" %}</legend>
|
||||
{% bootstrap_field sform.customer_accounts layout="control" %}
|
||||
{% bootstrap_field sform.customer_accounts_native layout="control" %}
|
||||
{% bootstrap_field sform.customer_accounts_to_oidc layout="control" %}
|
||||
{% bootstrap_field sform.customer_accounts_require_login_for_order_access layout="control" %}
|
||||
{% bootstrap_field sform.customer_accounts_link_by_email layout="control" %}
|
||||
{% bootstrap_field sform.name_scheme layout="control" %}
|
||||
|
||||
@@ -864,11 +864,33 @@ class SSOLoginReturnView(RedirectBackMixin, View):
|
||||
identifier=identifier,
|
||||
)
|
||||
except Customer.DoesNotExist:
|
||||
return self._fail(
|
||||
_('We were unable to use your login since the email address {email} is already used for a '
|
||||
'different account in this system.').format(email=profile['email']),
|
||||
popup_origin,
|
||||
)
|
||||
# no race-condition, try to convert to oidc?
|
||||
if self.provider.allow_convert_to_sso:
|
||||
try:
|
||||
customer = self.request.organizer.customers.get(
|
||||
email=profile['email'],
|
||||
)
|
||||
customer.set_unusable_password()
|
||||
customer.provider = self.provider
|
||||
customer.external_identifier = str(profile['uid'])
|
||||
customer.is_verified = True
|
||||
if name_parts:
|
||||
customer.name_parts = name_parts
|
||||
if profile.get('phone'):
|
||||
customer.phone = profile.get('phone')
|
||||
customer.save()
|
||||
except Customer.DoesNotExist:
|
||||
# should actually never happen
|
||||
return self._fail(
|
||||
_('We were unable to use your login since either the email address is unknown in this system.'),
|
||||
popup_origin,
|
||||
)
|
||||
else:
|
||||
return self._fail(
|
||||
_('We were unable to use your login since the email address {email} is already used for a '
|
||||
'different account in this system.').format(email=profile['email']),
|
||||
popup_origin,
|
||||
)
|
||||
else:
|
||||
if customer.is_active and customer.email != profile['email']:
|
||||
customer.email = profile['email']
|
||||
|
||||
@@ -438,6 +438,24 @@ def test_org_sso_login_new_customer_email_conflict(env, client, provider):
|
||||
_sso_login(client, provider, 'new@example.net', expect_fail=True)
|
||||
|
||||
|
||||
@pytest.mark.django_db(transaction=True)
|
||||
def test_org_sso_convert_customer_on_login(env, client, provider):
|
||||
organizer = env[0]
|
||||
provider.allow_convert_to_sso = True
|
||||
provider.save()
|
||||
with scopes_disabled():
|
||||
customer = organizer.customers.create(email='new@example.net', is_verified=True, is_active=False)
|
||||
customer.set_password('foo')
|
||||
customer.save()
|
||||
|
||||
_sso_login(client, provider, 'new@example.net')
|
||||
|
||||
customer.refresh_from_db()
|
||||
assert customer.provider
|
||||
assert customer.identifier
|
||||
assert not customer.has_usable_password()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize("url", [
|
||||
"account/change",
|
||||
|
||||
Reference in New Issue
Block a user