-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rename existingItem argument to item for access control functions #4074
Conversation
|
Any reason we couldn't retain Eg: - const existingItem = ....;
+ const item = ....;
return {
- existingItem,
+ // Deprecated in favour of `item`
+ existingItem: item,
+ item,
} |
@jesstelford we (@mitchellhamilton and I) talked about that -- we could even mark it as deprecated in the TypeScript types, which does a good job of making it clear in the editor for TypeScript users. However. Access control functions already need to be updated. Taking an example from our access control guide: access: ({ authentication, existingItem }) =>
authentication.item.isAdmin || authentication.item.id === existingItem.id This already needs to be rewritten as: access: ({ session, existingItem }) =>
session.data.isAdmin || session.itemId === existingItem.id At which point it might as well become: access: ({ session, item }) =>
session.data.isAdmin || session.itemId === item.id Particularly since you'd want to also add a new function to control views in the Admin UI, which will look like this: fieldMode: ({ session, item }) =>
session.data.isAdmin || session.itemId === item.id ? 'edit' : 'hidden' So the specific breaking change I'm proposing here doesn't have much impact on the refactor burden that already exists (for good reasons). And if we leave the duplicate (undocumented/deprecated even) argument around:
I think the second in particular has the potential to harm usability and clarity in this part of the system more I'm comfortable with, especially given the important of correctness and clarity when it comes to access control implementations. Finally, as a little bonus, aligning the arguments for access and viewMode (and similar) functions has a nice effect that it would be simpler to write sugary abstractions over. An example of how this might realistically be implemented: const isAdminOrItem = ({ session, item }) =>
session.data.isAdmin || session.itemId === item.id;
///
access: isAdminOrItem,
fieldMode: args => isAdminOrItem(args) ? 'edit' : 'hidden', Note that the arguments for both |
Why can't we do the same aliasing for
For those who can update now, sure, this makes sense. But for those who can't, it becomes a non-starter for upgrading. Instead of forcing extra work on them, we can be lenient and give them a grace period (I've often seen strategies of deprecation such as As someone who will want to upgrade to get access to other nice new things, I don't also want that upgrade to force me into having to go over all my custom access control (and hooks?) to update them, all for the sake of us adding 1 line to Keystone. |
So I think there's probably a few different things to consider here:
From the point of view of 1) 3) and 4) I think we should go ahead and make this change now, since this doesn't change anything in existing keystone, so there's no danger there. From the point of view of 2), I think this will be a comparatively low-impact change relative to other things that need to be changed in order to switch to the new APIs for an existing project. In particular, I suspect there are very few instances where This bigger question of how we make this transition as smooth as possible for pre-existing projects is something we need to be constantly keeping in mind as we move through this phase. In this instance there's probably a few different options on the table. We could ship it as is and get people to make the changes themselves, we could ship a wrapper that automatically translates the arguments, we could provide deprecated aliases as per Jess' suggestion above, and probably some other things that don't come to mind right now. Each of these options have tradeoffs. I think we should hold off making in a decision until we've had a chance to do some experiments with the new packages against pre-existing projects and we can see where the pain points are for transitioning. Adding backwards-compatibility helpers is totally a thing we will want to do, and adding these helpers in the future will be easier than removing them, so I think for today we should ship this as is and then revisit this discussion on backwards compatibility helpers and transition paths once we have a bit more experience with the impacts. |
Solid writeup @timleslie, thanks! With that in mind, I'm going to merge this, lets revisit those open points once the new interfaces have been in people's hands for a bit but before they go GA 👍 |
I like the words @timleslie said 👍 |
He does have a way 😀 |
cc/ @timleslie @molomby @mitchellhamilton
We talked not too long ago about whether we should change any of the arguments to access control functions and hooks for the new interfaces, and decided not to, in favour of reducing the upgrade complexity.
Since then, we've introduced new features to control things like
fieldMode
, which is designed to work alongside access control for better UX in the Admin UI. These take the newsession
argument and anitem
argument.These functions aren't exactly the same as what you'd write for access control, but very similar, so I want to propose the change in this PR -- to rename
existingItem
toitem
in the access control arguments (but not hooks)Rationale includes:
access
function signature is changing, unavoidably, because of the newsession
argument and because we can't reliably provide a truly backwards-compatibleauthentication
argument (and I'd argue that for this area of the system, because it's all about security, close enough is not good enough)existingItem
doesn't really make sense in access control -- for functions where there is an item to provide, it always exists, it's just the item. Access control always happens at the same part of the lifecycle so there's no ambiguity about what it is, unlike with hooksexistingItem
not the best name there, that's a whole other long conversation and I recognise the ambiguity involved in functions that are invoked in different parts of the operation lifecycle so I don't want to reopen thatThis really stood out to me as a problem while I was working on the new
auth
example, but I wanted to submit this as a discrete PR after that one landed so you can see specifically the change I want to make.