diff --git a/cookbook/helper/AllAuthCustomAdapter.py b/cookbook/helper/AllAuthCustomAdapter.py
index ba76bfca..64bf3c4d 100644
--- a/cookbook/helper/AllAuthCustomAdapter.py
+++ b/cookbook/helper/AllAuthCustomAdapter.py
@@ -9,7 +9,11 @@ class AllAuthCustomAdapter(DefaultAccountAdapter):
"""
Whether to allow sign ups.
"""
- allow_signups = super(
- AllAuthCustomAdapter, self).is_open_for_signup(request)
- # Override with setting, otherwise default to super.
- return getattr(settings, 'ACCOUNT_ALLOW_SIGNUPS', allow_signups)
+ if request.resolver_match.view_name == 'account_signup':
+ return False
+ else:
+ return super(AllAuthCustomAdapter, self).is_open_for_signup(request)
+
+ # disable password reset for now
+ def send_mail(self, template_prefix, email, context):
+ pass
diff --git a/cookbook/helper/permission_helper.py b/cookbook/helper/permission_helper.py
index 7093ac77..f6db4d81 100644
--- a/cookbook/helper/permission_helper.py
+++ b/cookbook/helper/permission_helper.py
@@ -119,7 +119,7 @@ def group_required(*groups_required):
def in_groups(u):
return has_group_permission(u, groups_required)
- return user_passes_test(in_groups)
+ return user_passes_test(in_groups, login_url='view_no_group')
class GroupRequiredMixin(object):
@@ -138,8 +138,7 @@ class GroupRequiredMixin(object):
)
return HttpResponseRedirect(reverse_lazy('index'))
- return super(GroupRequiredMixin, self) \
- .dispatch(request, *args, **kwargs)
+ return super(GroupRequiredMixin, self).dispatch(request, *args, **kwargs)
class OwnerRequiredMixin(object):
diff --git a/cookbook/templates/account/login.html b/cookbook/templates/account/login.html
new file mode 100644
index 00000000..6e3336e3
--- /dev/null
+++ b/cookbook/templates/account/login.html
@@ -0,0 +1,56 @@
+{% extends "base.html" %}
+{% load crispy_forms_filters %}
+{% load i18n %}
+
+{% load account socialaccount %}
+
+{% block title %}{% trans 'Login' %}{% endblock %}
+
+{% block content %}
+
+
+
+
{% trans "Sign In" %}
+
+
+
+
+
+
+ {% get_providers as socialaccount_providers %}
+
+ {% if socialaccount_providers %}
+
+
+
{% trans "Social Login" %}
+
{% trans 'You can use any of the following providers to sign in.' %}
+
+
+
+
+ {% include "socialaccount/snippets/provider_list.html" with process="login" %}
+
+
+
+ {% include "socialaccount/snippets/login_extra.html" %}
+
+
+
+
+ {% endif %}
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/cookbook/templates/account/logout.html b/cookbook/templates/account/logout.html
new file mode 100644
index 00000000..a4e29808
--- /dev/null
+++ b/cookbook/templates/account/logout.html
@@ -0,0 +1,22 @@
+{% extends "base.html" %}
+{% load crispy_forms_filters %}
+{% load i18n %}
+
+{% block title %}{% trans 'Sign Out' %}{% endblock %}
+
+
+{% block content %}
+ {% trans "Sign Out" %}
+
+ {% trans 'Are you sure you want to sign out?' %}
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/cookbook/templates/account/password_reset.html b/cookbook/templates/account/password_reset.html
new file mode 100644
index 00000000..a579ce9a
--- /dev/null
+++ b/cookbook/templates/account/password_reset.html
@@ -0,0 +1,11 @@
+{% extends "base.html" %}
+{% load crispy_forms_filters %}
+{% load i18n %}
+
+{% block title %}{% trans 'Password Reset' %}{% endblock %}
+
+
+{% block content %}
+ {% trans 'Password reset is not implemented for the time being!' %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/cookbook/templates/account/password_reset_done.html b/cookbook/templates/account/password_reset_done.html
new file mode 100644
index 00000000..a579ce9a
--- /dev/null
+++ b/cookbook/templates/account/password_reset_done.html
@@ -0,0 +1,11 @@
+{% extends "base.html" %}
+{% load crispy_forms_filters %}
+{% load i18n %}
+
+{% block title %}{% trans 'Password Reset' %}{% endblock %}
+
+
+{% block content %}
+ {% trans 'Password reset is not implemented for the time being!' %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/cookbook/templates/registration/signup.html b/cookbook/templates/account/signup.html
similarity index 100%
rename from cookbook/templates/registration/signup.html
rename to cookbook/templates/account/signup.html
diff --git a/cookbook/templates/no_groups_info.html b/cookbook/templates/no_groups_info.html
new file mode 100644
index 00000000..53b5f04c
--- /dev/null
+++ b/cookbook/templates/no_groups_info.html
@@ -0,0 +1,20 @@
+{% extends "base.html" %}
+{% load static %}
+{% load i18n %}
+
+{% block title %}{% trans "Offline" %}{% endblock %}
+
+
+{% block content %}
+
+
+
+
{% trans 'No Permissions' %}
+
+
+ {% trans 'You do not have any groups and therefor cannot use this application. Please contact your administrator.' %}
+
+
+
+{% endblock %}
+
diff --git a/cookbook/templates/registration/login.html b/cookbook/templates/registration/login.html
deleted file mode 100644
index 40b0497e..00000000
--- a/cookbook/templates/registration/login.html
+++ /dev/null
@@ -1,52 +0,0 @@
-{% extends "base.html" %}
-{% load i18n %}
-
-{% block title %}{% trans 'Login' %}{% endblock %}
-
-{% block content %}
-
- {% if form.errors %}
-
- {% trans "Your username and password didn't match. Please try again." %}
-
-
- {% endif %}
-
-
-
-
-
-{% endblock %}
\ No newline at end of file
diff --git a/cookbook/urls.py b/cookbook/urls.py
index ada427a5..ad6a7d98 100644
--- a/cookbook/urls.py
+++ b/cookbook/urls.py
@@ -39,6 +39,7 @@ router.register(r'supermarket', api.SupermarketViewSet)
urlpatterns = [
path('', views.index, name='index'),
path('setup/', views.setup, name='view_setup'),
+ path('no-group', views.no_groups, name='view_no_group'),
path('signup/', views.signup, name='view_signup'),
path('system/', views.system, name='view_system'),
path('search/', views.search, name='view_search'),
diff --git a/cookbook/views/views.py b/cookbook/views/views.py
index ce3a9b0d..57cf0e31 100644
--- a/cookbook/views/views.py
+++ b/cookbook/views/views.py
@@ -23,7 +23,7 @@ from cookbook.filters import RecipeFilter
from cookbook.forms import (CommentForm, Recipe, RecipeBookEntryForm, User,
UserCreateForm, UserNameForm, UserPreference,
UserPreferenceForm)
-from cookbook.helper.permission_helper import group_required, share_link_valid
+from cookbook.helper.permission_helper import group_required, share_link_valid, has_group_permission
from cookbook.models import (Comment, CookLog, InviteLink, MealPlan,
RecipeBook, RecipeBookEntry, ViewLog)
from cookbook.tables import (CookLogTable, RecipeTable, RecipeTableSmall,
@@ -34,8 +34,7 @@ from recipes.version import BUILD_REF, VERSION_NUMBER
def index(request):
if not request.user.is_authenticated:
- if (User.objects.count() < 1
- and 'django.contrib.auth.backends.RemoteUserBackend' not in settings.AUTHENTICATION_BACKENDS): # noqa: E501
+ if User.objects.count() < 1 and 'django.contrib.auth.backends.RemoteUserBackend' not in settings.AUTHENTICATION_BACKENDS:
return HttpResponseRedirect(reverse_lazy('view_setup'))
return HttpResponseRedirect(reverse_lazy('view_search'))
try:
@@ -45,15 +44,13 @@ def index(request):
UserPreference.BOOKS: reverse_lazy('view_books'),
}
- return HttpResponseRedirect(
- page_map.get(request.user.userpreference.default_page)
- )
+ return HttpResponseRedirect(page_map.get(request.user.userpreference.default_page))
except UserPreference.DoesNotExist:
- return HttpResponseRedirect(reverse('account_login') + '?next=' + request.path)
+ return HttpResponseRedirect(reverse('view_no_group') + '?next=' + request.path)
def search(request):
- if request.user.is_authenticated:
+ if has_group_permission(request.user, ('guest',)):
f = RecipeFilter(
request.GET,
queryset=Recipe.objects.all().order_by('name')
@@ -88,19 +85,27 @@ def search(request):
{'recipes': table, 'filter': f, 'last_viewed': last_viewed}
)
else:
- return HttpResponseRedirect(reverse('account_login') + '?next=' + request.path)
+ return HttpResponseRedirect(reverse('view_no_group') + '?next=' + request.path)
+
+
+def no_groups(request):
+ if not request.user.is_authenticated:
+ return HttpResponseRedirect(reverse('account_login') + '?next=' + request.GET['next'])
+ if request.user.is_authenticated and request.user.groups.count() > 0:
+ return HttpResponseRedirect(reverse('index'))
+ return render(request, 'no_groups_info.html')
def recipe_view(request, pk, share=None):
recipe = get_object_or_404(Recipe, pk=pk)
- if not request.user.is_authenticated and not share_link_valid(recipe, share):
+ if not has_group_permission(request.user, ('guest',)) and not share_link_valid(recipe, share):
messages.add_message(
request,
messages.ERROR,
_('You do not have the required permissions to view this page!')
)
- return HttpResponseRedirect(reverse('account_login') + '?next=' + request.path)
+ return HttpResponseRedirect(reverse('view_no_group') + '?next=' + request.path)
comments = Comment.objects.filter(recipe=recipe)
@@ -197,22 +202,6 @@ def books(request):
return render(request, 'books.html', {'book_list': book_list})
-def get_start_end_from_week(p_year, p_week):
- first_day_of_week = datetime.strptime(
- f'{p_year}-W{int(p_week) - 1}-1', "%Y-W%W-%w"
- ).date()
- last_day_of_week = first_day_of_week + timedelta(days=6.9)
- return first_day_of_week, last_day_of_week
-
-
-def get_days_from_week(start, end):
- delta = end - start
- days = []
- for i in range(delta.days + 1):
- days.append(start + timedelta(days=i))
- return days
-
-
@group_required('user')
def meal_plan(request):
return render(request, 'meal_plan.html', {})
@@ -466,7 +455,7 @@ def signup(request, token):
form.fields['name'].initial = link.username
form.fields['name'].disabled = True
return render(
- request, 'registration/signup.html', {'form': form, 'link': link}
+ request, 'account/signup.html', {'form': form, 'link': link}
)
messages.add_message(
diff --git a/docs/install/docker.md b/docs/install/docker.md
index 3cb9c140..ba6421b0 100644
--- a/docs/install/docker.md
+++ b/docs/install/docker.md
@@ -32,6 +32,20 @@ Please make sure, if you run your image this way, to consult
the [.env.template](https://raw.githubusercontent.com/vabene1111/recipes/master/.env.template)
file in the GitHub repository to verify if additional environment variables are required for your setup.
+### Versions
+
+There are different versions (tags) released on docker hub.
+
+- **latest** Default image. The one you should use if you don't know that you need anything else.
+- **beta** Partially stable version that gets updated every now and then. Expect to have some problems.
+- **develop** If you want the most bleeding edge version with potentially many breaking changes feel free to use this version (I don't recommend it!).
+- **X.Y.Z** each released version has its own image. If you need to revert to an old version or want to make sure you stay on one specific use these tags.
+
+!!! danger "No Downgrading"
+ There is currently no way to migrate back to an older version as there is no mechanism to downgrade the database.
+ You could probably do it but I cannot help you with that. Choose wisely if you want to use the unstable images.
+ That said **beta** should usually be working if you like frequent updates and new stuff.
+
## Docker Compose
The main, and also recommended, installation option is to install this application using Docker Compose.