diff --git a/lib/classes/JsonApi/Routes/Courses/Authority.php b/lib/classes/JsonApi/Routes/Courses/Authority.php
index db5a1d60f43ef2e21aa5158c14b9bd94d7d18d4b..197bb48240ad0067541ae1c60dc0e7416d0871b2 100644
--- a/lib/classes/JsonApi/Routes/Courses/Authority.php
+++ b/lib/classes/JsonApi/Routes/Courses/Authority.php
@@ -16,15 +16,16 @@ class Authority
     public static function canShowCourse(User $user, Course $course, $scope)
     {
         switch ($scope) {
-        case self::SCOPE_BASIC:
-            return
-                // visible
-                ((int) $course->visible) || $GLOBALS['perm']->have_perm(\Config::get()->SEM_VISIBILITY_PERM)
-                // member
-                || $GLOBALS['perm']->have_studip_perm('user', $course->id, $user->id);
-
-        case self::SCOPE_EXTENDED:
-            return $GLOBALS['perm']->have_studip_perm('user', $course->id, $user->id);
+            case self::SCOPE_BASIC:
+                return
+                    // visible
+                    $course->visible
+                    || $GLOBALS['perm']->have_perm(\Config::get()->SEM_VISIBILITY_PERM)
+                    // member
+                    || $GLOBALS['perm']->have_studip_perm('user', $course->id, $user->id);
+
+            case self::SCOPE_EXTENDED:
+                return $GLOBALS['perm']->have_studip_perm('user', $course->id, $user->id);
         }
 
         return false;
@@ -48,7 +49,7 @@ class Authority
 
     public static function canIndexMemberships(User $user, Course $course)
     {
-        return self::canShowCourse($user, $course, self::SCOPE_EXTENDED);
+        return self::canShowCourse($user, $course, self::SCOPE_BASIC);
     }
 
     public static function canIndexMembershipsOfUser(User $observer, User $user)
diff --git a/lib/classes/JsonApi/Routes/Courses/CoursesMembershipsIndex.php b/lib/classes/JsonApi/Routes/Courses/CoursesMembershipsIndex.php
index d4877bbe9692d08e941637caee36645d5c93d241..ceb2c8c5e672500a8a8ef200fa7b160e75a61b2a 100644
--- a/lib/classes/JsonApi/Routes/Courses/CoursesMembershipsIndex.php
+++ b/lib/classes/JsonApi/Routes/Courses/CoursesMembershipsIndex.php
@@ -45,19 +45,36 @@ class CoursesMembershipsIndex extends JsonApiController
     {
         $memberships = $course->members;
 
-        $visibleMemberships = Authority::canEditCourse($user, $course)
-            ? $memberships
-            : $memberships->filter(function ($membership) use ($user) {
-                return $membership['user_id'] == $user->id ||
-                    !in_array($membership['status'], ['autor', 'user']) ||
-                    'no' != $membership['visible'];
+        // Filter by permission?
+        if (isset($filters['permission'])) {
+            $memberships = $memberships->filter(function (\CourseMember $membership) use ($filters) {
+                return $membership->status === $filters['permission'];
             });
+        }
+
+        // Filter out invisible members if not teacher
+        if (!Authority::canEditCourse($user, $course)) {
+            $memberships = $memberships->filter(function (\CourseMember $membership) use ($user) {
+                return $membership->user->isAccessibleToUser($user->id)
+                    && (
+                        $membership->user_id === $user->id
+                        || $membership->visible !== 'no'
+                    );
+            });
+        }
+
+        // Filter out students if not in course
+        if (!Authority::canShowCourse($user, $course, Authority::SCOPE_EXTENDED)) {
+            $memberships = $memberships->filter(function (\CourseMember $membership) use ($user) {
+                return $membership->user->isAccessibleToUser($user->id)
+                    && (
+                        $membership->user_id === $user->id
+                        || !in_array($membership->status, ['autor', 'user'])
+                    );
+            });
+        }
 
-        return isset($filters['permission'])
-            ? $visibleMemberships->filter(function ($membership) use ($filters) {
-                return $membership['status'] === $filters['permission'];
-            })
-            : $visibleMemberships;
+        return $memberships;
     }
 
     private function validateFilters()
diff --git a/lib/models/User.php b/lib/models/User.php
index a7c8b6ef8b6db857c1b3a67377b81c182e6a706b..190df2b39468b2d673e2f806383997ad16723170 100644
--- a/lib/models/User.php
+++ b/lib/models/User.php
@@ -1507,13 +1507,15 @@ class User extends AuthUserMd5 implements Range, PrivacyObject, Studip\Calendar\
      */
     public function isAccessibleToUser($user_id = null)
     {
-        // TODO: Visibility checks
         if ($user_id === null) {
-            $user_id = $GLOBALS['user']->id;
+            $user_id = self::findCurrent()->id;
         }
+
         return $user_id === $this->user_id
             || static::find($user_id)->perms === 'root'
-            || !in_array(static::find($this->user_id)->visible, ['no', 'never']);
+            || !in_array($this->visible, ['no', 'never'])
+            || (Config::get()->getValue('USER_VISIBILITY_UNKNOWN') && $this->visible === 'unknown')
+            || ($this->perms === 'dozent' && Config::get()->getValue('DOZENT_ALWAYS_VISIBLE'));
     }
 
     /**