diff --git a/cookbook/helper/permission_helper.py b/cookbook/helper/permission_helper.py
index 5a131bffa..e1df06ada 100644
--- a/cookbook/helper/permission_helper.py
+++ b/cookbook/helper/permission_helper.py
@@ -455,3 +455,9 @@ class IsReadOnlyDRF(permissions.BasePermission):
def has_permission(self, request, view):
return request.method in SAFE_METHODS
+
+class IsCreateDRF(permissions.BasePermission):
+ message = 'You cannot interact with this object, you can only create'
+
+ def has_permission(self, request, view):
+ return request.method == 'POST'
\ No newline at end of file
diff --git a/cookbook/helper/scope_middleware.py b/cookbook/helper/scope_middleware.py
index b0efdfab4..92b8baee8 100644
--- a/cookbook/helper/scope_middleware.py
+++ b/cookbook/helper/scope_middleware.py
@@ -46,13 +46,15 @@ class ScopeMiddleware:
# get active user space, if for some reason more than one space is active select first (group permission checks will fail, this is not intended at this point)
user_space = request.user.userspace_set.filter(active=True).first()
- if not user_space:
- if request.user.userspace_set.count() > 0:
- # if the users has a userspace but nothing is active, activate the first one
- user_space = request.user.userspace_set.filter(active=True).first()
+ if not user_space and request.user.userspace_set.count() > 0:
+ # if the users has a userspace but nothing is active, activate the first one
+ user_space = request.user.userspace_set.first()
+ if user_space:
user_space.active = True
user_space.save()
- elif 'signup_token' in request.session:
+
+ if not user_space:
+ if 'signup_token' in request.session:
# if user is authenticated, has no space but a signup token (InviteLink) is present, redirect to invite link logic
return HttpResponseRedirect(reverse('view_invite', args=[request.session.pop('signup_token', '')]))
else:
diff --git a/cookbook/views/api.py b/cookbook/views/api.py
index 0c93c04ba..3d3421e27 100644
--- a/cookbook/views/api.py
+++ b/cookbook/views/api.py
@@ -75,7 +75,7 @@ from cookbook.helper.permission_helper import (CustomIsAdmin, CustomIsOwner, Cus
CustomTokenHasScope, CustomUserPermission, IsReadOnlyDRF,
above_space_limit,
group_required, has_group_permission, is_space_owner,
- switch_user_active_space, CustomAiProviderPermission
+ switch_user_active_space, CustomAiProviderPermission, IsCreateDRF
)
from cookbook.helper.recipe_search import RecipeSearch
from cookbook.helper.recipe_url_import import clean_dict, get_from_youtube_scraper, get_images_from_soup
@@ -546,7 +546,7 @@ class GroupViewSet(LoggingMixin, viewsets.ModelViewSet):
class SpaceViewSet(LoggingMixin, viewsets.ModelViewSet):
queryset = Space.objects
serializer_class = SpaceSerializer
- permission_classes = [IsReadOnlyDRF & CustomIsGuest | CustomIsOwner & CustomIsAdmin & CustomTokenHasReadWriteScope]
+ permission_classes = [((IsReadOnlyDRF | IsCreateDRF) & CustomIsGuest) | CustomIsOwner & CustomIsAdmin & CustomTokenHasReadWriteScope]
pagination_class = DefaultPagination
http_method_names = ['get', 'post', 'put', 'patch']
@@ -567,7 +567,7 @@ class SpaceViewSet(LoggingMixin, viewsets.ModelViewSet):
class UserSpaceViewSet(LoggingMixin, viewsets.ModelViewSet):
queryset = UserSpace.objects
serializer_class = UserSpaceSerializer
- permission_classes = [(CustomIsSpaceOwner | CustomIsOwnerReadOnly) & CustomTokenHasReadWriteScope]
+ permission_classes = [(CustomIsSpaceOwner | (IsReadOnlyDRF & CustomIsUser) | CustomIsOwnerReadOnly) & CustomTokenHasReadWriteScope]
http_method_names = ['get', 'put', 'patch', 'delete']
pagination_class = DefaultPagination
@@ -581,10 +581,23 @@ class UserSpaceViewSet(LoggingMixin, viewsets.ModelViewSet):
if internal_note is not None:
self.queryset = self.queryset.filter(internal_note=internal_note)
- if is_space_owner(self.request.user, self.request.space):
+ # starting with users you can SEE all other users in a space, guests only see themselves
+ if has_group_permission(self.request.user, ['user']):
return self.queryset.filter(space=self.request.space)
else:
- return self.queryset.filter(user=self.request.user, space=self.request.space)
+ return self.queryset.filter(space=self.request.space, user=self.request.user)
+
+ @extend_schema(responses=UserSpaceSerializer(many=True))
+ @decorators.action(detail=False, pagination_class=DefaultPagination, methods=['GET'], serializer_class=UserSpaceSerializer, )
+ def all_personal(self, request):
+ """
+ return all userspaces for the user requesting the endpoint
+ :param request:
+ :return:
+ """
+ with scopes_disabled():
+ self.queryset = self.queryset.filter(user=self.request.user)
+ return Response(self.serializer_class(self.queryset.all(), many=True, context={'request': self.request}).data)
class UserPreferenceViewSet(LoggingMixin, viewsets.ModelViewSet):
diff --git a/vue3/src/apps/tandoor/Tandoor.vue b/vue3/src/apps/tandoor/Tandoor.vue
index 541cdb6ed..241611856 100644
--- a/vue3/src/apps/tandoor/Tandoor.vue
+++ b/vue3/src/apps/tandoor/Tandoor.vue
@@ -163,7 +163,7 @@ onMounted(() => {
* global title update handler, might be overridden by page specific handlers
*/
router.afterEach((to, from) => {
- if(to.name != 'WelcomePage' && !useUserPreferenceStore().activeSpace.spaceSetupCompleted && useUserPreferenceStore().activeSpace.createdBy.id! == useUserPreferenceStore().userSettings.user.id!){
+ if(to.name == 'StartPage' && !useUserPreferenceStore().activeSpace.spaceSetupCompleted && useUserPreferenceStore().activeSpace.createdBy.id! == useUserPreferenceStore().userSettings.user.id!){
router.push({name: 'WelcomePage'})
}
nextTick(() => {
diff --git a/vue3/src/components/inputs/UserFileField.vue b/vue3/src/components/inputs/UserFileField.vue
index 99ca367db..dbdac091c 100644
--- a/vue3/src/components/inputs/UserFileField.vue
+++ b/vue3/src/components/inputs/UserFileField.vue
@@ -98,7 +98,7 @@