project: Moodle
summary: Moodle LMS / MoodleNet integration project - Phase 1
description: This project aims to expand the integration between Moodle LMS and MoodleNet, with the main goal being to facilitate the transfer of content from Moodle LMS into MoodleNet. The key personas in this project will be teachers and site admins. . MVP for Moodle 4.2 The key user stories related to the teacher persona are: As a teacher, I can "connect" my LMS account to a MoodleNet account, so that it is authorised to share content to MoodleNet. As a teacher, I can synchronously share a single activity/resource to MoodleNet as a Moodle backup file, so it is available for others to import into their Moodle courses. As a teacher, I can see which MoodleNet site I am sharing to, so I know where my content will be uploaded. As a teacher, I will be provided with a link to my draft resource on MoodleNet, so I can complete any additional metadata requirements and publish my resource. As a teacher, I will be notified if an attempt to share to MoodleNet fails, so I can take appropriate action. As a teacher, while I am waiting for my share to MoodleNet to complete, I will see multiple status updates, so I have a clear indication that the packaging and uploading of my resource is progressing. (Note: This user story is a "nice to have" and will be completed within phase 1 if time allows, but is not critical for the phase 1 MVP to function or land). Current teacher journey prototype| The key user stories related to the site admin persona are: As a site admin, I can enable or disable teachers access to share to the MoodleNet site I have configured, so I have control over whether the content is published outside of my LMS. As a site admin, I can configure MoodleNet sites as OAuth 2 issuers, so that the issuer sites are available to me when configuring "share to MoodleNet" functionality in my LMS. As a site admin, I can set any configured MoodleNet OAuth 2 issuer as the available MoodleNet instance to share to, so it is easy for teachers to authorise their LMS account to share to their account on that MoodleNet instance, and so I can control which MoodleNet instance this is allowed for. As a site admin, I can view a log of all content that has been shared (or attempted to be shared) from the LMS instance to MoodleNet, so I can ensure policies and licensing are adhered to. These admin user stories follow established site administration patterns, so a prototype is not necessary at this stage (UX designers and writers will still be engaged to review the content). . Future work / Out of scope The following milestones are currently beyond the MVP project scope as sprints available will not allow for the work required on both the LMS and MoodleNet sides to be completed in time for LMS 4.2 code freeze / release. Ability for teachers to share the contents of a whole course as a Moodle backup file to MoodleNet, so others can import and use the course they have written. (Note: User/student data is not included). A "share history" interface for teachers, which allows them to view the history of content they have sent to MoodleNet. Support for connecting to multiple MoodleNet instances. In phase 1 it may be possible to configure multiple MoodleNet OAut issuers, however it will only be possible to activate sharing to one. More granular control over course sharing (the ability to select/deselect activities). The ability for activities/resources to define whether they can be shared as a "link" or an individual "file", rather than a Moodle backup. Asynchronous uploads, to allow larger data transfers in the background, so teachers can continue to use the current LMS tab without waiting for a full backup/file to be sent. Any updates to the existing implementation of MoodleNet to LMS functionality. This will likely be re-implemented to more closely integrate with the new LMS to MoodleNet functionality in a later release.

1.summary: Add oautservice_moodlenet plugin
description: Based on work done in , this issue is scoped with adding the relevant oautservice_moodlenet plugin. This will allow Moodle to use the resulting service for MoodleNet API calls in future issues. You can see the other plugins in lib/oaut/ for reference (once is done) . This plugin should support the following OAuth 2 Authorization Server Metadata (aka discovery using this standard) Open OAuth 2 Dynamic Client Registration This must use the open configuration since: a) Moodle.net is the planned target and will have open registration for client apps. b) There isnt currently a means to support token-base registration in core Moodle. The issuer forms only permit registration via the "Base URL" field, and dont allow for tokens to be entered (yet - this may change in the OAuth 2 improvements in future) The plugin config should specify that it requires base URL (this is needed so that discovery, and then registration can take place) as well as indicate support for the above 2 features (discovery, registration) Template should contain the application URL (this can be changed) . User stories This issue helps satisfy the following user stories: As a site admin, I can configure MoodleNet sites as OAuth 2 services, so that the services are available to me when configuring "share to MoodleNet" functionality in my LMS. As a teacher, I can "connect" my LMS account to a MoodleNet account, so that it is authorised to share content to MoodleNet. Note: This will satisfy 1, and is a part of satisfying 2 (since the auth code flow made by the teacher hasnt yet been implemented). . Completion criteria I can create a new MoodleNet OAuth 2 service via a button on the OAuth 2 services page Upon creation, the client_id and client_secret are provided to Moodle and saved Upon creation, the relevant OAuth 2 endpoints will be automatically discovered and populated No user field mappings are present after creation (this is not an identity service)
2.summary: (PARENT) Implement LMS foundation for sharing content to MoodleNet (share activities)
description: This issue is to collect the core features required to share activities to MoodleNet as a backup file, so they can be integrated together. This is the minimum functionality required for the feature to be functional. The key issues collected under this issue for integration are as follows (full requirements and user stories outlined in each of the respective issues): - Create necessary site admin settings and capability to control the feature being available, and which MoodleNet instance content can be shared to. - Create core MoodleNet component and APIs to facilitate sharing resources to MoodleNet. - Create web service(s) which perform necessary checks (eg capability) and utilise the API from 2. - Implement the Share to MoodleNet modal and activity menu item (create necessary UI to use the feature).
3.summary: Build a mock MoodleNet API endpoint for LMS MoodleNet testing
description: A mock MoodleNet endpoint should be created to represent API calls being made between LMS and MoodleNet, primarily to facilitate easy automated testing runs (such as CI testing), as well as more complex development testing (compared with the basics available from ). The basic setup of this can possibly be copied from the existing BigBlueButton or Matrix equivalent, and then have the API built out onto that. Requirements A mock API endpoint for the MoodleNet API side of share to MoodleNet , which accepts valid requests for OAuth metadata, registration and MoodleNet API calls, and provides accurate responses. Handling for unexpected/invalid requests, as necessary to perform LMS testing. May need data storage for tests (will eventually, but potentially not required for phase 1). If it will be running on CI, it must handle multiple clients - i.e. behat parallel runs on different base URLs storing data separately and clearing it separately. Needs to run either as a docker image, or locally. An important consideration is that Moodles OAuth provider implementation requires or it will be rejected, so this will likely need to handle that (which is not currently supported in the BBB mock setup).
4.summary: Implement the Share to MoodleNet modal and activity menu item
description: This issue relates to creating the required modal content to allow sharing of resources to MoodleNet, and linking to the modal from the relevant menu. . Requirements Share to MoodleNet item in activity/resource "More" secondary navigation menu, if a user has the appropriate capability to share to MoodleNet. The menu item will open a modal. All stages of the share process are displayed within the same modal (just re-rendered with the new content). The first view of the modal shows the activity type/name and which MoodleNet site it will be shared to (as per the prototype), along with an option to perform the share. When pressing the Share action: The share button should trigger an OAuth authorisation prompt on MoodleNet if authorisation has not already been granted (ie first time sharing to this MoodleNet site). If authorisation is not granted (eg they cancel), they should be returned to the first modal screen (where they can hit Share again to repeat the process). Once authorised (either above, or if already previously authorised), a web service will be called to facilitate the packaging and sharing of the content. When the share is initiated, a second waiting/loading modal view will be shown (as per the prototype). The scope for this issue is only to show the loading spinner in this state, no specific progress updates. Once a success response and MoodleNet resource URL are received from the web service, the success view will be shown in the modal, which includes a button which links to the draft MoodleNet resource URL (which would open in a new tab). The user will need to press the button to be taken to the resource, it will not be auto-opened. If the upload fails (ie the web service returns a fail), display the fail version of the final modal screen (fail state prototype TBC). . User stories This issue resolves the following user stories: As a teacher, I need the ability to share individual activities/resources onto MoodleNet, so that they are available for other MoodleNet users to utilise. As a teacher, I can see which MoodleNet site I am sharing to, so I know where my content will be uploaded. As a teacher, I will be provided with a link to my draft resource on MoodleNet, so I can complete any additional metadata requirements and publish my resource. . Out of scope Any specific status updates on the loading screen. The scope of this issue only covers showing the loading screen with spinner, and the final success/fail state. Other status checks will be implemented in . Any link to a "share history" for the teacher (the share history is out of scope for this stage of the project, so will not exist). Share an activity/resource from the course homepage. A single point of action (within the activity) will be the only entry point to share to MoodleNet. Asynchronous packaging and file transfer (for this phase, the user will wait for the file and metadata to be sent, and for the LMS to receive the relevant ID/URL, then they will be provided with the link to the draft MoodleNet resource).
5.summary: Design MoodleNet resource API
description: This is scoped with defining/designing MoodleNets public API for resources.
6.summary: Design a new subsystem containing MoodleNet features
description: This is scoped with: Clarification on what the current definition of a subsystem is (vs just a core API) Should clarify current expectations for building a subsystem Discuss possible naming/scopes for the new subsystem (content, sharing, etc.)
7.summary: Investigate: Authentication options for the Moodlenet integration
description: Investigate and document some options, detailing feasibility, strength, weaknesses, actors, etc. Have had initial meeting and will begin 27/06/22.
8.summary: MoodleNet integration project - Hedgehogs sprint 0.1 next steps / requirements gathering (LMS to MoodleNet data flow)
description: Placeholder for next steps in sprint 1 for the MoodleNet project. More info TBC soon.
9.summary: Investigation and proof of concept for packaging content for MoodleNet
description: Before work begins on actual implementation of user flows etc, we need to spend some time investigating what is possible with the existing backup functionality, to allow us to package and send content to MoodleNet. The end aim for this issue is to prepare a proof of concept for selecting activities and creating a backup file without any user data, bypassing all of the usual backup process steps, since the "sending to MoodleNet" process will need to obscure those steps from the user.
10.summary: Finalise MVP priorities for the LMS to MoodleNet integration and log issues
description: Finalise the high level priorities/milestones for the 4.1 MoodleNet integration project for data travelling from LMS to MoodleNet, and log relevant issues in Tracker (even if only a high level summary until further prototypes are developed).
11.summary: Define LMS to MoodleNet user flow and finalise MVP UX designs
description: The flow for users sending content from LMS to MoodleNet needs to be investigated and defined. Once that is determined, the UX designs for the project MVP user journeys need to be progressed to a state thats ready for UI development to begin in a following sprint.
12.summary: Determine suitability of existing OAut issuer code
description: This issue has the following goals: - Determine whether the existing issuer architecture is compatible with MoodleNets proposed OAut API. Specifically, check compatibility with: - "OAuth 2.0 Authorization Server Metadata" ( - "OAuth 2.0 Dynamic Client Registration" ( - Describe any changes required to support the above specifications - Describe any outstanding points which need further discussion
13.summary: Add OAuth 2.0 Authorization Server Metadata support to issuers and create MoodleNet issuer
description: See for details about the issuer code and a description of the changes I think are needed. Essentially, MoodleNet (subsystem or otherwise) will need a way to create an issuer using metadata discovery that follows the relevant spec. This may also involve a tidy up of the existing code structure as per comments on . We should be able to test this is working by doing the following: 1. Publishing an example JSON metadata file on another local Moodle site somewhere 2. Adding the relevant issuer using the other sites base URL. It should be able to read the metadata from the /.well-known/oauth-authorization-server endpoint and create the relevant endpoints against the issuer. Given the issuer can only be created using dynamic registration, that should be included here too.
14.summary: Create core\moodlenet APIs
description: This issue involves creating the _moodlenet_ component in core and the key API(s) and backend functionality required to share specified LMS content to MoodleNet. . Requirements This component will exist in core Moodle, so will require the following: Main API class(es) to be located in a new lib/classes/moodlenet directory. Appropriate update to lib/apis.json. An API that, for a specified activity/resource and MoodleNet site, has the ability to send a Moodle backup (.mbz) of that resource (prepared by 4 below) to the MoodleNet site, using a single multipart request via Guzzle as per MoodleNet s API specification| In the above MoodleNet API call, the title will be the activity name (required) and description will be the activity description (if it exists, otherwise empty). Ability to package a specified activity as a Moodle backup file, which contains the base activity content (ie no users or user data, grades etc). A proof of concept is available at . This requirement can be separated into its own issue if necessary to reduce scope on this issue. The API method that is called to share the content to MoodleNet should return the resulting MoodleNet URL. When the relevant web service is implemented in a follow up issue, this will be used to provide the user with a link to the draft resource that has been created. Logging to admin logs of all share attempts, including details of what was being shared and whether it was successful/failed. The maximum file size supported by HQ MoodleNet is 1.2GB, so we need to ensure this is not exceeded before sending. Note: This may be configurable within MoodleNet instances (not clear whether it is _yet_), but there is currently no way to retrieve that information. PHPUnit testing coverage. Some considerations which should be factored in when naming/architecting relevant classes and methods: The MoodleNet API spec is still a WIP, the endpoint URLs are subject to change (this is not a blocker, any changes can be made in a follow up). In phase 2, it will also be possible to send a course backup (which includes specified activities within the course). In phase 2 or later, we will not be limiting scope to sending as a backup, there may be other types, such as sending the raw file from a file resource (which would be the same as a backup without the MBZ generation step), or sending a URL instead of a file (which won t require multipart). . User stories This issue helps satisfy the following user story: As a site admin, I can view a log of all content that has been shared (or attempted to be shared) from the LMS instance to MoodleNet, so I can ensure policies and licensing are adhered to. Although this issue does not provide any functionality directly to teachers, it creates the framework to help satisfy the following user stories: As a teacher, I can synchronously share a single activity/resource to MoodleNet as a Moodle backup file, so it is available for others to import into their Moodle courses. As a teacher, I will be provided with a link to my draft resource on MoodleNet, so I can complete any additional metadata requirements and publish my resource. As a teacher, I will be notified if an attempt to share to MoodleNet fails, so I can take appropriate action. As a teacher, while I am waiting for my share to MoodleNet to complete, I will see multiple status updates, so I have a clear indication that the packaging and uploading of my resource is progressing. . Out of scope Web services, they will be created in . Checking we can reach the MoodleNet site before packaging and attempting to send the resource. This will be implemented in . File cleanup, implemented by . Logging for teachers information, covered by (and won t be visible to teachers in phase 1).
15.summary: Implement web services for sharing content to MoodleNet
description: One or more new web services are required which utilise the APIs created in , to facilitate sharing to MoodleNet. For the scope of this issue, it will likely only require a single web service. . Requirements Parameters: cmid of the activity to be shared. Returns: MoodleNet draft resource URL. As this functionality lives in core, any web services will be located in lib/classes/external. Although in this phase of the project only a single MoodleNet instance will be available (so the teacher will not be able to change it in the UI), we should still require passing in the relevant MoodleNet site. This will future proof for later phases when multiple MoodleNet sites may be enabled for sharing. We could potentially also pass in a parameter for share format, which in the current scope would always be an activity backup (in future there would be options for raw file or URL). All operations must perform appropriate validation and capability checks (eg the capability created in ) to ensure they are allowed to perform the relevant action. For example: The user performing the action is allowed to share to MoodleNet. The user is allowed to share the content they are trying to share. The MoodleNet site specified is one which the admin has enabled for sharing to (in this phase, it will have to match the one option that has been configured). Unit testing as appropriate. . User stories Although this issue does not provide any functionality directly to teachers, it makes the relevant API available to the frontend which will help satisfy the following user stories: As a teacher, I can synchronously share a single activity/resource to MoodleNet as a Moodle backup file, so it is available for others to import into their Moodle courses. As a teacher, I will be provided with a link to my draft resource on MoodleNet, so I can complete any additional metadata requirements and publish my resource. As a teacher, I will be notified if an attempt to share to MoodleNet fails, so I can take appropriate action. As a site admin, I can enable or disable teachers access to share to the MoodleNet site I have configured, so I have control over whether the content is published outside of my LMS. . Out of scope Only the final success/fail status of the share/upload needs to be covered by the web service. Additional status updates (eg packaging) will be implemented separately on . This web service only needs to handle sharing a single activity. In future, when course sharing is implemented, this will be covered by a separate web service. That means we should not need to factor course sharing into the design of this web service (except perhaps keeping it in mind we will want to name things in such a way that can be reused consistently with course, eg something like moodlenet_share_activity / moodlenet_share_single, so later we can be consistent with something like moodlenet_share_course).
16.summary: Add site administration config to control sharing to MoodleNet
description: MoodleNet sharing functionality requires some site administration settings to control access to sharing to MoodleNet and which MoodleNet instance can be shared to. . Requirements Since the sharing _to_ MoodleNet functionality is in core and independent from the existing settings for content being sent from MoodleNet _into_ the LMS, it will need to be be a separate section in settings. As discussed with huongn it should be possible to include this on the same, but under separate sections (to keep all MoodleNet related settings on the same general > MoodleNet category. I would suggest we rename the existing section from "MoodleNet settings" to "MoodleNet inbound settings" and include the new settings under "MoodleNet outbound settings". The sharing to MoodleNet functionality needs to be behind an experimental feature flag, which controls whether it is enabled or disabled for the site (disabled by default since it is experimental). A single select dropdown is required to select which MoodleNet instance can be shared to. The options should be all MoodleNet OAuth 2 providers that have been configured on the Moodle instance. Although multiple MoodleNet providers may be configured in OAuth settings, the scope for phase 1 of this project is to only allow one of them to be enabled for sharing to. If no MoodleNet OAuth providers are configured, the dropdown in 3 should be disabled with the validation indicating that at least one provider needs to be configured to use it. The description for the setting added in 3 should clearly outline what the setting is for, and hyperlink to the relevant site admin page to configure MoodleNet OAuth providers (so if the list is empty/incomplete, the admin can easily navigate to complete setting it up). The settings should use progressive disclosure , where the options such as which site is available to share to should be hidden until the share to MoodleNet feature is enabled (the setting in requirement 2). In this issue we should also create a new capability for being able to share to MoodleNet, which is given to editing teachers and managers by default. All following project issues will require both the admin settings and capability, so it makes sense to implement them together here first. Behat/unit tests implemented as applicable. . User stories This issue resolves the following user story: As a site admin, I can set any configured MoodleNet OAuth 2 issuer as the available MoodleNet instance to share to, so it is easy for teachers to authorise their LMS account to share to their account on that MoodleNet instance, and so I can control which MoodleNet instance this is allowed for.
17.summary: Build a small local endpoint for local / unit testing MoodleNet sharing
description: To avoid spending a lot of time with a full docker implementation of a mock endpoint (which can be built later via ), we should create a basic endpoint (probably using Guzzle) that can run locally to respond to metadata, registration and API requests, so initial unit testing can be created without being blocked by the larger piece of work.
18.summary: Implement MoodleNet shared file cleanup
description: When a resource is shared to MoodleNet as an activity backup, that backup will be created and occupy space on the server. We should perform relevant cleanup operations to ensure these are not stored indefinitely, either after the file has successfully be uploaded to MoodleNet, or after failure to send (since we currently do not have a way to retry the file again later). Two of the possible implementations are either as a scheduled task to perform the cleanup, OR on-demand, so the sharing API cleans up as it completes its task (which may be easier since it will only have to keep track of the file it has created, whereas a scheduled task may not be able to easily distinguish which files are no longer needed).

Below is an instruction that describes a task, paired with an input that provides an epic with this format: 
"project": "Name of the project" 
"summary": "Summary of the epic user story" 
"description": "Description of the epic user story". Write a response that appropriately completes the request.### Instruction:
Break this epic user story into smaller tasks to help the developers understand the epic better, you can divide this epic into as much as you want depending on the complexity of the epic.
### Input:
project: Moodle
summary: Moodle LMS / MoodleNet integration project - Phase 1
description: This project aims to expand the integration between Moodle LMS and MoodleNet, with the main goal being to facilitate the transfer of content from Moodle LMS into MoodleNet. The key personas in this project will be teachers and site admins. . MVP for Moodle 4.2 The key user stories related to the teacher persona are: As a teacher, I can "connect" my LMS account to a MoodleNet account, so that it is authorised to share content to MoodleNet. As a teacher, I can synchronously share a single activity/resource to MoodleNet as a Moodle backup file, so it is available for others to import into their Moodle courses. As a teacher, I can see which MoodleNet site I am sharing to, so I know where my content will be uploaded. As a teacher, I will be provided with a link to my draft resource on MoodleNet, so I can complete any additional metadata requirements and publish my resource. As a teacher, I will be notified if an attempt to share to MoodleNet fails, so I can take appropriate action. As a teacher, while I am waiting for my share to MoodleNet to complete, I will see multiple status updates, so I have a clear indication that the packaging and uploading of my resource is progressing. (Note: This user story is a "nice to have" and will be completed within phase 1 if time allows, but is not critical for the phase 1 MVP to function or land). Current teacher journey prototype| The key user stories related to the site admin persona are: As a site admin, I can enable or disable teachers access to share to the MoodleNet site I have configured, so I have control over whether the content is published outside of my LMS. As a site admin, I can configure MoodleNet sites as OAuth 2 issuers, so that the issuer sites are available to me when configuring "share to MoodleNet" functionality in my LMS. As a site admin, I can set any configured MoodleNet OAuth 2 issuer as the available MoodleNet instance to share to, so it is easy for teachers to authorise their LMS account to share to their account on that MoodleNet instance, and so I can control which MoodleNet instance this is allowed for. As a site admin, I can view a log of all content that has been shared (or attempted to be shared) from the LMS instance to MoodleNet, so I can ensure policies and licensing are adhered to. These admin user stories follow established site administration patterns, so a prototype is not necessary at this stage (UX designers and writers will still be engaged to review the content). . Future work / Out of scope The following milestones are currently beyond the MVP project scope as sprints available will not allow for the work required on both the LMS and MoodleNet sides to be completed in time for LMS 4.2 code freeze / release. Ability for teachers to share the contents of a whole course as a Moodle backup file to MoodleNet, so others can import and use the course they have written. (Note: User/student data is not included). A "share history" interface for teachers, which allows them to view the history of content they have sent to MoodleNet. Support for connecting to multiple MoodleNet instances. In phase 1 it may be possible to configure multiple MoodleNet OAut issuers, however it will only be possible to activate sharing to one. More granular control over course sharing (the ability to select/deselect activities). The ability for activities/resources to define whether they can be shared as a "link" or an individual "file", rather than a Moodle backup. Asynchronous uploads, to allow larger data transfers in the background, so teachers can continue to use the current LMS tab without waiting for a full backup/file to be sent. Any updates to the existing implementation of MoodleNet to LMS functionality. This will likely be re-implemented to more closely integrate with the new LMS to MoodleNet functionality in a later release.

### Response:
1.summary: Add oautservice_moodlenet plugin
description: Based on work done in , this issue is scoped with adding the relevant oautservice_moodlenet plugin. This will allow Moodle to use the resulting service for MoodleNet API calls in future issues. You can see the other plugins in lib/oaut/ for reference (once is done) . This plugin should support the following OAuth 2 Authorization Server Metadata (aka discovery using this standard) Open OAuth 2 Dynamic Client Registration This must use the open configuration since: a) Moodle.net is the planned target and will have open registration for client apps. b) There isnt currently a means to support token-base registration in core Moodle. The issuer forms only permit registration via the "Base URL" field, and dont allow for tokens to be entered (yet - this may change in the OAuth 2 improvements in future) The plugin config should specify that it requires base URL (this is needed so that discovery, and then registration can take place) as well as indicate support for the above 2 features (discovery, registration) Template should contain the application URL (this can be changed) . User stories This issue helps satisfy the following user stories: As a site admin, I can configure MoodleNet sites as OAuth 2 services, so that the services are available to me when configuring "share to MoodleNet" functionality in my LMS. As a teacher, I can "connect" my LMS account to a MoodleNet account, so that it is authorised to share content to MoodleNet. Note: This will satisfy 1, and is a part of satisfying 2 (since the auth code flow made by the teacher hasnt yet been implemented). . Completion criteria I can create a new MoodleNet OAuth 2 service via a button on the OAuth 2 services page Upon creation, the client_id and client_secret are provided to Moodle and saved Upon creation, the relevant OAuth 2 endpoints will be automatically discovered and populated No user field mappings are present after creation (this is not an identity service)
2.summary: (PARENT) Implement LMS foundation for sharing content to MoodleNet (share activities)
description: This issue is to collect the core features required to share activities to MoodleNet as a backup file, so they can be integrated together. This is the minimum functionality required for the feature to be functional. The key issues collected under this issue for integration are as follows (full requirements and user stories outlined in each of the respective issues): - Create necessary site admin settings and capability to control the feature being available, and which MoodleNet instance content can be shared to. - Create core MoodleNet component and APIs to facilitate sharing resources to MoodleNet. - Create web service(s) which perform necessary checks (eg capability) and utilise the API from 2. - Implement the Share to MoodleNet modal and activity menu item (create necessary UI to use the feature).
3.summary: Build a mock MoodleNet API endpoint for LMS MoodleNet testing
description: A mock MoodleNet endpoint should be created to represent API calls being made between LMS and MoodleNet, primarily to facilitate easy automated testing runs (such as CI testing), as well as more complex development testing (compared with the basics available from ). The basic setup of this can possibly be copied from the existing BigBlueButton or Matrix equivalent, and then have the API built out onto that. Requirements A mock API endpoint for the MoodleNet API side of share to MoodleNet , which accepts valid requests for OAuth metadata, registration and MoodleNet API calls, and provides accurate responses. Handling for unexpected/invalid requests, as necessary to perform LMS testing. May need data storage for tests (will eventually, but potentially not required for phase 1). If it will be running on CI, it must handle multiple clients - i.e. behat parallel runs on different base URLs storing data separately and clearing it separately. Needs to run either as a docker image, or locally. An important consideration is that Moodles OAuth provider implementation requires or it will be rejected, so this will likely need to handle that (which is not currently supported in the BBB mock setup).
4.summary: Implement the Share to MoodleNet modal and activity menu item
description: This issue relates to creating the required modal content to allow sharing of resources to MoodleNet, and linking to the modal from the relevant menu. . Requirements Share to MoodleNet item in activity/resource "More" secondary navigation menu, if a user has the appropriate capability to share to MoodleNet. The menu item will open a modal. All stages of the share process are displayed within the same modal (just re-rendered with the new content). The first view of the modal shows the activity type/name and which MoodleNet site it will be shared to (as per the prototype), along with an option to perform the share. When pressing the Share action: The share button should trigger an OAuth authorisation prompt on MoodleNet if authorisation has not already been granted (ie first time sharing to this MoodleNet site). If authorisation is not granted (eg they cancel), they should be returned to the first modal screen (where they can hit Share again to repeat the process). Once authorised (either above, or if already previously authorised), a web service will be called to facilitate the packaging and sharing of the content. When the share is initiated, a second waiting/loading modal view will be shown (as per the prototype). The scope for this issue is only to show the loading spinner in this state, no specific progress updates. Once a success response and MoodleNet resource URL are received from the web service, the success view will be shown in the modal, which includes a button which links to the draft MoodleNet resource URL (which would open in a new tab). The user will need to press the button to be taken to the resource, it will not be auto-opened. If the upload fails (ie the web service returns a fail), display the fail version of the final modal screen (fail state prototype TBC). . User stories This issue resolves the following user stories: As a teacher, I need the ability to share individual activities/resources onto MoodleNet, so that they are available for other MoodleNet users to utilise. As a teacher, I can see which MoodleNet site I am sharing to, so I know where my content will be uploaded. As a teacher, I will be provided with a link to my draft resource on MoodleNet, so I can complete any additional metadata requirements and publish my resource. . Out of scope Any specific status updates on the loading screen. The scope of this issue only covers showing the loading screen with spinner, and the final success/fail state. Other status checks will be implemented in . Any link to a "share history" for the teacher (the share history is out of scope for this stage of the project, so will not exist). Share an activity/resource from the course homepage. A single point of action (within the activity) will be the only entry point to share to MoodleNet. Asynchronous packaging and file transfer (for this phase, the user will wait for the file and metadata to be sent, and for the LMS to receive the relevant ID/URL, then they will be provided with the link to the draft MoodleNet resource).
5.summary: Design MoodleNet resource API
description: This is scoped with defining/designing MoodleNets public API for resources.
6.summary: Design a new subsystem containing MoodleNet features
description: This is scoped with: Clarification on what the current definition of a subsystem is (vs just a core API) Should clarify current expectations for building a subsystem Discuss possible naming/scopes for the new subsystem (content, sharing, etc.)
7.summary: Investigate: Authentication options for the Moodlenet integration
description: Investigate and document some options, detailing feasibility, strength, weaknesses, actors, etc. Have had initial meeting and will begin 27/06/22.
8.summary: MoodleNet integration project - Hedgehogs sprint 0.1 next steps / requirements gathering (LMS to MoodleNet data flow)
description: Placeholder for next steps in sprint 1 for the MoodleNet project. More info TBC soon.
9.summary: Investigation and proof of concept for packaging content for MoodleNet
description: Before work begins on actual implementation of user flows etc, we need to spend some time investigating what is possible with the existing backup functionality, to allow us to package and send content to MoodleNet. The end aim for this issue is to prepare a proof of concept for selecting activities and creating a backup file without any user data, bypassing all of the usual backup process steps, since the "sending to MoodleNet" process will need to obscure those steps from the user.
10.summary: Finalise MVP priorities for the LMS to MoodleNet integration and log issues
description: Finalise the high level priorities/milestones for the 4.1 MoodleNet integration project for data travelling from LMS to MoodleNet, and log relevant issues in Tracker (even if only a high level summary until further prototypes are developed).
11.summary: Define LMS to MoodleNet user flow and finalise MVP UX designs
description: The flow for users sending content from LMS to MoodleNet needs to be investigated and defined. Once that is determined, the UX designs for the project MVP user journeys need to be progressed to a state thats ready for UI development to begin in a following sprint.
12.summary: Determine suitability of existing OAut issuer code
description: This issue has the following goals: - Determine whether the existing issuer architecture is compatible with MoodleNets proposed OAut API. Specifically, check compatibility with: - "OAuth 2.0 Authorization Server Metadata" ( - "OAuth 2.0 Dynamic Client Registration" ( - Describe any changes required to support the above specifications - Describe any outstanding points which need further discussion
13.summary: Add OAuth 2.0 Authorization Server Metadata support to issuers and create MoodleNet issuer
description: See for details about the issuer code and a description of the changes I think are needed. Essentially, MoodleNet (subsystem or otherwise) will need a way to create an issuer using metadata discovery that follows the relevant spec. This may also involve a tidy up of the existing code structure as per comments on . We should be able to test this is working by doing the following: 1. Publishing an example JSON metadata file on another local Moodle site somewhere 2. Adding the relevant issuer using the other sites base URL. It should be able to read the metadata from the /.well-known/oauth-authorization-server endpoint and create the relevant endpoints against the issuer. Given the issuer can only be created using dynamic registration, that should be included here too.
14.summary: Create core\moodlenet APIs
description: This issue involves creating the _moodlenet_ component in core and the key API(s) and backend functionality required to share specified LMS content to MoodleNet. . Requirements This component will exist in core Moodle, so will require the following: Main API class(es) to be located in a new lib/classes/moodlenet directory. Appropriate update to lib/apis.json. An API that, for a specified activity/resource and MoodleNet site, has the ability to send a Moodle backup (.mbz) of that resource (prepared by 4 below) to the MoodleNet site, using a single multipart request via Guzzle as per MoodleNet s API specification| In the above MoodleNet API call, the title will be the activity name (required) and description will be the activity description (if it exists, otherwise empty). Ability to package a specified activity as a Moodle backup file, which contains the base activity content (ie no users or user data, grades etc). A proof of concept is available at . This requirement can be separated into its own issue if necessary to reduce scope on this issue. The API method that is called to share the content to MoodleNet should return the resulting MoodleNet URL. When the relevant web service is implemented in a follow up issue, this will be used to provide the user with a link to the draft resource that has been created. Logging to admin logs of all share attempts, including details of what was being shared and whether it was successful/failed. The maximum file size supported by HQ MoodleNet is 1.2GB, so we need to ensure this is not exceeded before sending. Note: This may be configurable within MoodleNet instances (not clear whether it is _yet_), but there is currently no way to retrieve that information. PHPUnit testing coverage. Some considerations which should be factored in when naming/architecting relevant classes and methods: The MoodleNet API spec is still a WIP, the endpoint URLs are subject to change (this is not a blocker, any changes can be made in a follow up). In phase 2, it will also be possible to send a course backup (which includes specified activities within the course). In phase 2 or later, we will not be limiting scope to sending as a backup, there may be other types, such as sending the raw file from a file resource (which would be the same as a backup without the MBZ generation step), or sending a URL instead of a file (which won t require multipart). . User stories This issue helps satisfy the following user story: As a site admin, I can view a log of all content that has been shared (or attempted to be shared) from the LMS instance to MoodleNet, so I can ensure policies and licensing are adhered to. Although this issue does not provide any functionality directly to teachers, it creates the framework to help satisfy the following user stories: As a teacher, I can synchronously share a single activity/resource to MoodleNet as a Moodle backup file, so it is available for others to import into their Moodle courses. As a teacher, I will be provided with a link to my draft resource on MoodleNet, so I can complete any additional metadata requirements and publish my resource. As a teacher, I will be notified if an attempt to share to MoodleNet fails, so I can take appropriate action. As a teacher, while I am waiting for my share to MoodleNet to complete, I will see multiple status updates, so I have a clear indication that the packaging and uploading of my resource is progressing. . Out of scope Web services, they will be created in . Checking we can reach the MoodleNet site before packaging and attempting to send the resource. This will be implemented in . File cleanup, implemented by . Logging for teachers information, covered by (and won t be visible to teachers in phase 1).
15.summary: Implement web services for sharing content to MoodleNet
description: One or more new web services are required which utilise the APIs created in , to facilitate sharing to MoodleNet. For the scope of this issue, it will likely only require a single web service. . Requirements Parameters: cmid of the activity to be shared. Returns: MoodleNet draft resource URL. As this functionality lives in core, any web services will be located in lib/classes/external. Although in this phase of the project only a single MoodleNet instance will be available (so the teacher will not be able to change it in the UI), we should still require passing in the relevant MoodleNet site. This will future proof for later phases when multiple MoodleNet sites may be enabled for sharing. We could potentially also pass in a parameter for share format, which in the current scope would always be an activity backup (in future there would be options for raw file or URL). All operations must perform appropriate validation and capability checks (eg the capability created in ) to ensure they are allowed to perform the relevant action. For example: The user performing the action is allowed to share to MoodleNet. The user is allowed to share the content they are trying to share. The MoodleNet site specified is one which the admin has enabled for sharing to (in this phase, it will have to match the one option that has been configured). Unit testing as appropriate. . User stories Although this issue does not provide any functionality directly to teachers, it makes the relevant API available to the frontend which will help satisfy the following user stories: As a teacher, I can synchronously share a single activity/resource to MoodleNet as a Moodle backup file, so it is available for others to import into their Moodle courses. As a teacher, I will be provided with a link to my draft resource on MoodleNet, so I can complete any additional metadata requirements and publish my resource. As a teacher, I will be notified if an attempt to share to MoodleNet fails, so I can take appropriate action. As a site admin, I can enable or disable teachers access to share to the MoodleNet site I have configured, so I have control over whether the content is published outside of my LMS. . Out of scope Only the final success/fail status of the share/upload needs to be covered by the web service. Additional status updates (eg packaging) will be implemented separately on . This web service only needs to handle sharing a single activity. In future, when course sharing is implemented, this will be covered by a separate web service. That means we should not need to factor course sharing into the design of this web service (except perhaps keeping it in mind we will want to name things in such a way that can be reused consistently with course, eg something like moodlenet_share_activity / moodlenet_share_single, so later we can be consistent with something like moodlenet_share_course).
16.summary: Add site administration config to control sharing to MoodleNet
description: MoodleNet sharing functionality requires some site administration settings to control access to sharing to MoodleNet and which MoodleNet instance can be shared to. . Requirements Since the sharing _to_ MoodleNet functionality is in core and independent from the existing settings for content being sent from MoodleNet _into_ the LMS, it will need to be be a separate section in settings. As discussed with huongn it should be possible to include this on the same, but under separate sections (to keep all MoodleNet related settings on the same general > MoodleNet category. I would suggest we rename the existing section from "MoodleNet settings" to "MoodleNet inbound settings" and include the new settings under "MoodleNet outbound settings". The sharing to MoodleNet functionality needs to be behind an experimental feature flag, which controls whether it is enabled or disabled for the site (disabled by default since it is experimental). A single select dropdown is required to select which MoodleNet instance can be shared to. The options should be all MoodleNet OAuth 2 providers that have been configured on the Moodle instance. Although multiple MoodleNet providers may be configured in OAuth settings, the scope for phase 1 of this project is to only allow one of them to be enabled for sharing to. If no MoodleNet OAuth providers are configured, the dropdown in 3 should be disabled with the validation indicating that at least one provider needs to be configured to use it. The description for the setting added in 3 should clearly outline what the setting is for, and hyperlink to the relevant site admin page to configure MoodleNet OAuth providers (so if the list is empty/incomplete, the admin can easily navigate to complete setting it up). The settings should use progressive disclosure , where the options such as which site is available to share to should be hidden until the share to MoodleNet feature is enabled (the setting in requirement 2). In this issue we should also create a new capability for being able to share to MoodleNet, which is given to editing teachers and managers by default. All following project issues will require both the admin settings and capability, so it makes sense to implement them together here first. Behat/unit tests implemented as applicable. . User stories This issue resolves the following user story: As a site admin, I can set any configured MoodleNet OAuth 2 issuer as the available MoodleNet instance to share to, so it is easy for teachers to authorise their LMS account to share to their account on that MoodleNet instance, and so I can control which MoodleNet instance this is allowed for.
17.summary: Build a small local endpoint for local / unit testing MoodleNet sharing
description: To avoid spending a lot of time with a full docker implementation of a mock endpoint (which can be built later via ), we should create a basic endpoint (probably using Guzzle) that can run locally to respond to metadata, registration and API requests, so initial unit testing can be created without being blocked by the larger piece of work.
18.summary: Implement MoodleNet shared file cleanup
description: When a resource is shared to MoodleNet as an activity backup, that backup will be created and occupy space on the server. We should perform relevant cleanup operations to ensure these are not stored indefinitely, either after the file has successfully be uploaded to MoodleNet, or after failure to send (since we currently do not have a way to retry the file again later). Two of the possible implementations are either as a scheduled task to perform the cleanup, OR on-demand, so the sharing API cleans up as it completes its task (which may be easier since it will only have to keep track of the file it has created, whereas a scheduled task may not be able to easily distinguish which files are no longer needed).
