diff --git a/kolibri/core/device/serializers.py b/kolibri/core/device/serializers.py index a34e681e69a..81f5f49a06a 100644 --- a/kolibri/core/device/serializers.py +++ b/kolibri/core/device/serializers.py @@ -13,6 +13,7 @@ from kolibri.core.content.tasks import automatic_synchronize_content_requests_and_import from kolibri.core.device.models import DevicePermissions from kolibri.core.device.models import DeviceSettings +from kolibri.core.device.models import OSUser from kolibri.core.device.utils import APP_AUTH_TOKEN_COOKIE_NAME from kolibri.core.device.utils import provision_device from kolibri.core.device.utils import provision_single_user_device @@ -76,8 +77,7 @@ class Meta: def validate(self, data): if ( - "superuser" not in data - and GET_OS_USER in interface + GET_OS_USER in interface and "request" in self.context and valid_app_key_on_request(self.context["request"]) ): @@ -163,7 +163,7 @@ def create(self, validated_data): # noqa C901 auth_token = validated_data.pop("auth_token", None) - if not auth_token: + if "superuser" in validated_data: superuser_data = validated_data["superuser"] # We've imported a facility if the username exists try: @@ -183,11 +183,22 @@ def create(self, validated_data): # noqa C901 raise ParseError( "`username`, `password`, or `full_name` are missing in `superuser`" ) + if auth_token: + # If we have an auth token, we need to create an OSUser for the superuser + # so that we can associate the user with the OSUser + os_username, _ = interface.get_os_user(auth_token) + OSUser.objects.update_or_create( + os_username=os_username, defaults={"user": superuser} + ) - else: + elif auth_token: superuser = FacilityUser.objects.get_or_create_os_user( auth_token, facility=facility ) + else: + raise ParseError( + "Either `superuser` or `auth_token` must be provided for provisioning" + ) is_soud = validated_data.pop("is_soud") diff --git a/kolibri/plugins/setup_wizard/assets/src/machines/wizardMachine.js b/kolibri/plugins/setup_wizard/assets/src/machines/wizardMachine.js index e3003a68e37..e6b52db6da5 100644 --- a/kolibri/plugins/setup_wizard/assets/src/machines/wizardMachine.js +++ b/kolibri/plugins/setup_wizard/assets/src/machines/wizardMachine.js @@ -239,23 +239,10 @@ export const wizardMachine = createMachine( BACK: 'requirePassword', }, }, - // A passthrough step depending on the value of context.canGetOsUser - the finalizeSetup state - // will provision the device with the OS user and create the default facility - createSuperuserAndFacility: { - on: { BACK: 'personalDataConsent' }, - always: [ - { - cond: 'canGetOsUser', - target: 'finalizeSetup', - }, - { - target: 'createSuperuserAndFacilityForm', - }, - ], - }, - // If we're not able to get an OS user, the user creates their account - createSuperuserAndFacilityForm: { + // In the group learning flow we always create the account on the device + // and the backend associates it with the created superuser. + createSuperuserAndFacility: { meta: { route: { name: 'CREATE_SUPERUSER_AND_FACILITY', path: 'create-account' } }, on: { CONTINUE: { target: 'finalizeSetup', actions: 'setSuperuser' }, diff --git a/kolibri/plugins/setup_wizard/assets/src/views/onboarding-forms/SettingUpKolibri.vue b/kolibri/plugins/setup_wizard/assets/src/views/onboarding-forms/SettingUpKolibri.vue index d8dadc40edd..e26eca6e8e2 100644 --- a/kolibri/plugins/setup_wizard/assets/src/views/onboarding-forms/SettingUpKolibri.vue +++ b/kolibri/plugins/setup_wizard/assets/src/views/onboarding-forms/SettingUpKolibri.vue @@ -120,9 +120,9 @@ /** The data we will use to initialize the device during provisioning */ deviceProvisioningData() { let superuser = null; - // We only need a superuser if we cannot get the OS user; null valued keys will be omitted - // in the eventual API call - if (!checkCapability('get_os_user')) { + // We need the superuser information unless the superuser will be created at login, + // based on the os user - this is only the case for on my own setup. + if (!(this.isOnMyOwnSetup && checkCapability('get_os_user'))) { // Here we see if we've set a firstImportedLodUser -- if they exist, they must be the // superuser as they were the first imported user. if (this.wizardContext('firstImportedLodUser')) { @@ -154,7 +154,6 @@ this.$tr('onMyOwnDeviceName', { name: get(superuser, 'full_name', '') }).slice(0, 50), allow_guest_access: Boolean(this.wizardContext('guestAccess')), is_provisioned: true, - os_user: checkCapability('get_os_user'), is_soud: this.wizardContext('fullOrLOD') === DeviceTypePresets.LOD, };