Repository: learningequality/kolibri

Issue:
users go to Classes page by default even when not enrolled in a class


### Observed behavior

e.g. an admin not enrolled in a class goes here when clicking on 'Learn'

![image](https://user-images.githubusercontent.com/2367265/85485903-8465eb00-b57e-11ea-9492-894f13e45dd3.png)


### Expected behavior

land on Channels instead

### Context

0.14.0 beta 3


Discussion:
I have a feeling that this might be due to a race condition, because everything in this screenshot is indicating that this `handler` should have done that right thing and gone to "Channels":

1. The "Channels" and "Recommended" tab are visible, so `canAccessUnassignedContent` must be `true`
1. There are no classes cards, so `memberships.length > 0` must be false
1. Therefore, In the `ROOT` handler (below), we should have redirected to `TOPICS_ROOT` aka "Channels"

It's possible that because it's hard to predict the timing of when `handler`s get executed relative to other async code, that `!canAccessUnassignedContent` can evaluate to `true` (in spite of how the device is configured, etc.), causing the redirect to `ALL_CLASSES`

```
  {
    name: PageNames.ROOT,
    path: '/',
    handler: () => {
      const { memberships } = store.state;
      const { canAccessUnassignedContent } = store.getters;

      // If a registered user, go to Classes Page, else go to Content
      return router.replace({
        name:
          memberships.length > 0 || !canAccessUnassignedContent
            ? ClassesPageNames.ALL_CLASSES
            : PageNames.TOPICS_ROOT,
      });
    },
  },
```

I think the fix I'll try is to add a secondary guard inside the `AllClassesPage` to redirect back to the Channels page if:

1. `memberships.length === 0` and
1. `getters.canAccessUnassignedContent` is `true`


Resolving patch:
diff --git a/kolibri/core/auth/models.py b/kolibri/core/auth/models.py
--- a/kolibri/core/auth/models.py
+++ b/kolibri/core/auth/models.py
@@ -69,7 +69,6 @@
 from .permissions.general import IsSelf
 from kolibri.core.auth.constants.demographics import choices as GENDER_CHOICES
 from kolibri.core.auth.constants.morango_sync import ScopeDefinitions
-from kolibri.core.device.utils import allow_learner_unassigned_resource_access
 from kolibri.core.device.utils import DeviceNotProvisioned
 from kolibri.core.device.utils import get_device_setting
 from kolibri.core.device.utils import set_device_settings
@@ -493,10 +492,6 @@ def filter_readable(self, queryset):
             "Subclasses of KolibriAbstractBaseUser must override the `can_delete` method."
         )
 
-    @property
-    def can_access_unassigned_content(self):
-        return allow_learner_unassigned_resource_access()
-
 
 class KolibriAnonymousUser(AnonymousUser, KolibriAbstractBaseUser):
     """
@@ -514,7 +509,6 @@ def session_data(self):
             "user_id": None,
             "facility_id": getattr(Facility.get_default_facility(), "id", None),
             "kind": [user_kinds.ANONYMOUS],
-            "can_access_unassigned_content": self.can_access_unassigned_content,
         }
 
     def is_member_of(self, coll):
@@ -730,18 +724,12 @@ def session_data(self):
         if not roles:
             roles = [user_kinds.LEARNER]
 
-        can_access_unassigned_content = self.can_access_unassigned_content
-
-        if len(set(roles).difference({user_kinds.LEARNER, user_kinds.ANONYMOUS})) > 0:
-            can_access_unassigned_content = True
-
         return {
             "username": self.username,
             "full_name": self.full_name,
             "user_id": self.id,
             "kind": roles,
             "can_manage_content": self.can_manage_content,
-            "can_access_unassigned_content": can_access_unassigned_content,
             "facility_id": self.facility_id,
         }
 
diff --git a/kolibri/plugins/learn/kolibri_plugin.py b/kolibri/plugins/learn/kolibri_plugin.py
--- a/kolibri/plugins/learn/kolibri_plugin.py
+++ b/kolibri/plugins/learn/kolibri_plugin.py
@@ -7,6 +7,7 @@
 from kolibri.core.auth.constants.user_kinds import ANONYMOUS
 from kolibri.core.auth.constants.user_kinds import LEARNER
 from kolibri.core.content.hooks import ContentNodeDisplayHook
+from kolibri.core.device.utils import allow_learner_unassigned_resource_access
 from kolibri.core.device.utils import get_device_setting
 from kolibri.core.device.utils import is_landing_page
 from kolibri.core.device.utils import LANDING_PAGE_LEARN
@@ -47,7 +48,10 @@ class LearnAsset(webpack_hooks.WebpackBundleHook):
 
     @property
     def plugin_data(self):
-        return {"allowGuestAccess": get_device_setting("allow_guest_access")}
+        return {
+            "allowGuestAccess": get_device_setting("allow_guest_access"),
+            "allowLearnerUnassignedResourceAccess": allow_learner_unassigned_resource_access(),
+        }
 
 
 @register_hook


Test patch:
diff --git a/kolibri/plugins/learn/assets/test/views/learn-index.spec.js b/kolibri/plugins/learn/assets/test/views/learn-index.spec.js
--- a/kolibri/plugins/learn/assets/test/views/learn-index.spec.js
+++ b/kolibri/plugins/learn/assets/test/views/learn-index.spec.js
@@ -65,8 +65,7 @@ describe('learn plugin index page', () => {
     store.state.pageName = pageName;
   };
   const setCanAccessUnassignedContent = canAccess => {
-    store.state.core.session.can_access_unassigned_content = canAccess;
-    store.state.core.allowRemoteAccess = canAccess;
+    store.state.canAccessUnassignedContentSetting = canAccess;
   };
 
   beforeEach(() => {