many signup and space management fixes

This commit is contained in:
vabene1111 2021-06-07 16:46:28 +02:00
parent bf467b1ec0
commit 3074d916dc
12 changed files with 49 additions and 61 deletions

View File

@ -166,7 +166,7 @@ admin.site.register(ViewLog, ViewLogAdmin)
class InviteLinkAdmin(admin.ModelAdmin):
list_display = (
'username', 'group', 'valid_until',
'group', 'valid_until',
'created_by', 'created_at', 'used_by'
)

View File

@ -413,19 +413,11 @@ class InviteLinkForm(forms.ModelForm):
return email
def clean_username(self):
username = self.cleaned_data['username']
with scopes_disabled():
if username != '' and (User.objects.filter(username=username).exists() or InviteLink.objects.filter(username=username).exists()):
raise ValidationError(_('Username already taken!'))
return username
class Meta:
model = InviteLink
fields = ('username', 'email', 'group', 'valid_until', 'space')
fields = ('email', 'group', 'valid_until', 'space')
help_texts = {
'username': _('A username is not required, if left blank the new user can choose one.'),
'email': _('An email address is not required but if present the invite link will be send to the user.')
'email': _('An email address is not required but if present the invite link will be send to the user.'),
}
field_classes = {
'space': SafeModelChoiceField,

View File

@ -16,7 +16,10 @@ class ScopeMiddleware:
with scopes_disabled():
return self.get_response(request)
if request.path.startswith('/signup/'):
if request.path.startswith('/signup/') or request.path.startswith('/invite/'):
return self.get_response(request)
if request.path.startswith('/accounts/'):
return self.get_response(request)
with scopes_disabled():

View File

@ -0,0 +1,17 @@
# Generated by Django 3.2.3 on 2021-06-07 14:21
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0126_alter_userpreference_theme'),
]
operations = [
migrations.RemoveField(
model_name='invitelink',
name='username',
),
]

View File

@ -612,7 +612,6 @@ def default_valid_until():
class InviteLink(ExportModelOperationsMixin('invite_link'), models.Model, PermissionModelMixin):
uuid = models.UUIDField(default=uuid.uuid4)
username = models.CharField(blank=True, max_length=64)
email = models.EmailField(blank=True)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
valid_until = models.DateField(default=default_valid_until)

View File

@ -141,7 +141,7 @@ class ShoppingListTable(tables.Table):
class InviteLinkTable(tables.Table):
link = tables.TemplateColumn(
"<input value='{{ request.scheme }}://{{ request.get_host }}{% url 'view_signup' record.uuid %}' class='form-control' />"
"<input value='{{ request.scheme }}://{{ request.get_host }}{% url 'view_invite' record.uuid %}' class='form-control' />"
)
delete_link = tables.TemplateColumn(
"<a href='{% url 'delete_invite_link' record.pk %}' >" + _('Delete') + "</a>", verbose_name=_('Delete')

View File

@ -25,6 +25,9 @@
<div class="form-group">
{{ form.email |as_crispy_field }}
</div>
<div class="form-group">
{{ form.email2 |as_crispy_field }}
</div>
<div class="form-group">
{{ form.password1 |as_crispy_field }}
</div>

View File

@ -96,10 +96,10 @@
<div class="input-group mb-3">
<select v-model="users['{{ u.pk }}']" class="custom-select form-control"
style="height: 44px">
<option>{% trans 'admin' %}</option>
<option>{% trans 'user' %}</option>
<option>{% trans 'guest' %}</option>
<option>{% trans 'remove' %}</option>
<option value="admin">{% trans 'admin' %}</option>
<option value="user">{% trans 'user' %}</option>
<option value="guest">{% trans 'guest' %}</option>
<option value="remove">{% trans 'remove' %}</option>
</select>
<span class="input-group-append">
<a class="btn btn-warning"

View File

@ -48,7 +48,8 @@ urlpatterns = [
path('no-group', views.no_groups, name='view_no_group'),
path('no-space', views.no_space, name='view_no_space'),
path('no-perm', views.no_perm, name='view_no_perm'),
path('signup/<slug:token>', views.signup, name='view_signup'),
path('signup/<slug:token>', views.signup, name='view_signup'), # TODO deprecated with 0.16.2 remove at some point
path('invite/<slug:token>', views.invite_link, name='view_invite'),
path('system/', views.system, name='view_system'),
path('search/', views.search, name='view_search'),
path('search/v2/', views.search_v2, name='view_search_v2'),

View File

@ -225,7 +225,7 @@ class InviteLinkCreate(GroupRequiredMixin, CreateView):
if InviteLink.objects.filter(space=self.request.space, created_at__gte=datetime.now() - timedelta(hours=4)).count() < 20:
message = _('Hello') + '!\n\n' + _('You have been invited by ') + escape(self.request.user.username)
message += _(' to join their Tandoor Recipes space ') + escape(self.request.space.name) + '.\n\n'
message += _('Click the following link to activate your account: ') + self.request.build_absolute_uri(reverse('view_signup', args=[str(obj.uuid)])) + '\n\n'
message += _('Click the following link to activate your account: ') + self.request.build_absolute_uri(reverse('view_invite', args=[str(obj.uuid)])) + '\n\n'
message += _('If the link does not work use the following code to manually join the space: ') + str(obj.uuid) + '\n\n'
message += _('The invitation is valid until ') + str(obj.valid_until) + '\n\n'
message += _('Tandoor Recipes is an Open Source recipe manager. Check it out on GitHub ') + 'https://github.com/vabene1111/recipes/'

View File

@ -126,7 +126,7 @@ def no_space(request):
return HttpResponseRedirect(reverse('index'))
if join_form.is_valid():
return HttpResponseRedirect(reverse('view_signup', args=[join_form.cleaned_data['token']]))
return HttpResponseRedirect(reverse('view_invite', args=[join_form.cleaned_data['token']]))
else:
if settings.SOCIAL_DEFAULT_ACCESS:
request.user.userpreference.space = Space.objects.first()
@ -134,7 +134,7 @@ def no_space(request):
request.user.groups.add(Group.objects.get(name=settings.SOCIAL_DEFAULT_GROUP))
return HttpResponseRedirect(reverse('index'))
if 'signup_token' in request.session:
return HttpResponseRedirect(reverse('view_signup', args=[request.session.pop('signup_token', '')]))
return HttpResponseRedirect(reverse('view_invite', args=[request.session.pop('signup_token', '')]))
create_form = SpaceCreateForm()
join_form = SpaceJoinForm()
@ -420,7 +420,7 @@ def setup(request):
return render(request, 'setup.html', {'form': form})
def signup(request, token):
def invite_link(request, token):
with scopes_disabled():
try:
token = UUID(token, version=4)
@ -446,47 +446,15 @@ def signup(request, token):
return HttpResponseRedirect(reverse('index'))
else:
request.session['signup_token'] = str(token)
return HttpResponseRedirect(reverse('account_signup'))
if request.method == 'POST':
updated_request = request.POST.copy()
if link.username != '':
updated_request.update({'username': link.username})
messages.add_message(request, messages.ERROR, _('Invite Link not valid or already used!'))
return HttpResponseRedirect(reverse('index'))
form = SignupForm(data=updated_request)
if form.is_valid():
if form.cleaned_data['password1'] != form.cleaned_data['password_confirm']: # noqa: E501
form.add_error('password1', _('Passwords dont match!'))
else:
user = User(username=form.cleaned_data['username'], )
try:
validate_password(form.cleaned_data['password1'], user=user)
user.set_password(form.cleaned_data['password1'])
user.save()
messages.add_message(request, messages.SUCCESS, _('User has been created, please login!'))
link.used_by = user
link.save()
request.user.groups.clear()
user.groups.add(link.group)
user.userpreference.space = link.space
user.userpreference.save()
return HttpResponseRedirect(reverse('account_login'))
except ValidationError as e:
for m in e:
form.add_error('password', m)
else:
form = SignupForm()
if link.username != '':
form.fields['name'].initial = link.username
form.fields['name'].disabled = True
return render(request, 'account/signup.html', {'form': form, 'link': link})
messages.add_message(request, messages.ERROR, _('Invite Link not valid or already used!'))
return HttpResponseRedirect(reverse('index'))
# TODO deprecated with 0.16.2 remove at some point
def signup(request, token):
return HttpResponseRedirect(reverse('view_invite', args=[token]))
@group_required('admin')

View File

@ -113,6 +113,11 @@ INSTALLED_APPS = [
SOCIAL_PROVIDERS = os.getenv('SOCIAL_PROVIDERS').split(',') if os.getenv('SOCIAL_PROVIDERS') else []
INSTALLED_APPS = INSTALLED_APPS + SOCIAL_PROVIDERS
ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE = True
ACCOUNT_MAX_EMAIL_ADDRESSES = 3
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 90
SOCIALACCOUNT_PROVIDERS = ast.literal_eval(
os.getenv('SOCIALACCOUNT_PROVIDERS') if os.getenv('SOCIALACCOUNT_PROVIDERS') else '{}')