openedx / openedx-learning

GNU Affero General Public License v3.0
5 stars 8 forks source link

docs: ADR for serving static assets #110

Closed ormsbee closed 9 months ago

ormsbee commented 10 months ago

A first stab at an asset serving ADR that could serve Studio and the LMS. I'm especially looking for feedback on how we could do the cookie auth handoff (or for someone to tell me why it's a terrible idea).

ormsbee commented 10 months ago

@connorhaugh:

I think an implicit choice made is that there is a 1-1 mapping of assets to xblocks. We, however, know that reuse of assets is very common across blocks. How does that square with permissions and versioning?

The mapping isn't really 1:1 though. The raw data for the asset lives in a file referenced by a RawContent model. But that same asset can exist in many different XBlock components. It can even exist as multiple different file names within the same XBlock if we really want it to, though I can't think of a plausible use case for that.

In terms of re-use, I think there are two scenarios that can play out:

Incidental re-use, with component-local assets.

We upload a cute cat image in one problem, and then upload it (and a few others) in a second problem in the same library. We're effectively "re-using" the image data, but not in any way that requires centralized management. The system saves the raw data once, but there are two different rows of ComponentVersionRawContent that reference it. The two images will be available at two different URLs and can have separate permissions checks applied, since they are addressed as part of two different XBlock components, and the system may give a 403 for one you're not yet allowed to see.

Intentional re-use, with centralized management.

I think this one's trickier, because there are a couple flavors.

The first kind is linking to the assets of other Components directly. Under the covers, this is how existing Files and Uploads in Studio would be handled (with a Component that represents all the current files and uploads stored for a course). Things could be linked directly, and anyone enrolled in the course would have access to it.

There's also linking to a shared asset where the dependency is more explicitly tracked. Say we have a library of custom grader code, that includes both Python code that can be executed, as well as JavaScript code for certain problem types. Our component XBlock (a ProblemBlock) uses these assets. There are a few broad approaches I can think of:

  1. Optimize for the browser by downloading things from the original component location, even if that's in another Learning Package. This is the best for browser caching, especially if we're using it across many different ProblemBlocks in our course, but it can make permissions checking difficult.
  2. Make the download URL of the shared content appear to be nested inside the borrowing component–i.e. make it look like the asset belongs to the ProblemBlock and not wherever it originally came from. This simplifies permissions checking because you're only ever checking that you have permissions to the ProblemBlock, not to anything it might be using.
  3. Something in between, possibly at the LearningPackage level.
ormsbee commented 10 months ago

Made some major revisions. I'll probably ping the forums for more eyes this coming week.

ormsbee commented 9 months ago

@bradenmacdonald: Finally getting back to this. Addressed your last comment about how an object store should no longer be a requirement. Honestly relieved to not have to try to push that change through just yet. 😛

ormsbee commented 9 months ago

@connorhaugh: I've included your edit suggestion. Please let me know if you have any other concerns.