-
Notifications
You must be signed in to change notification settings - Fork 29
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
Rework Lock API metadata and add missing argument to Unlock #162
Rework Lock API metadata and add missing argument to Unlock #162
Conversation
After all, it's totally equivalent: either the expiration time is implemented on setting the value, or when checking it. The timeout itself (e.g. the 30 minutes for WOPI) is either way a parameter of the server configuration. That said I'm happy with the change if you like it more... |
Now if we go ahead and change the API, let's also think about the signatures for the methods requiring to validate against a given |
Having an expiration timestamp is easier in that case. The client (eg. WOPI server) can calculate that (having a config option for that). When setting an lock (begin) timestamp, the storage driver needs to know how long a lock should last. This would then be a config option of the storage driver. Therefore I would go for the expiration timestamp and dedicate this power to the clients instead to the storage.
I'm fine with that, too. |
One more thing. The docs explicitly name the JSON properties. While |
Oh ... another thing: in WebDAV we can use a Depth:infinity header when locking a collection. It indicates that all transitive children in a collection are covered by the lock. We could send that as Metadata, or as an optional And should metadata be a |
OK, agreed that For the format of the For the depth: I never thought about recursively locking a container with its children, i.e. I always implicitly assumed depth = 0. I'm not really sure we want to go as far as allowing a user to lock a folder and all its content - and implement the consequent logic at the level of ocdav for sync client and web UI. So I'd rather spell out in the docs that |
on the grpc level the oneof semantic works ... it is just that the json representation for that does not work as documented. I will continue with my webdav lock implmentation to see where this is going and what the code looks like when trying to actually enforce the locks. Regarding depth: WOPI only deals with file locks. But webdav also 'dabbles' with folder locks ;-) Iwould be happy to assume depth:0 for now ... unfortunately, webdav assumes depth:infinity: http://www.webdav.org/specs/rfc2518.html#rfc.section.8.10.4
So, I'll go forward, assuming depth:infinity for all requests, but only allow it for files. No need to send the depth in the lock for new. Can be added when implementing locks on collections. |
Finally, |
In fact we're in parallel working at the eos implementation and likely finding pitfalls/details to be sorted out. For the depth, I agree with you, let's leave it out for now even though WebDAV assumes Finally, for the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As just discussed at our virtual coffee break, we can go ahead as is for now and merge this PR.
Joern is going to look if a more generic metadata
payload (map of opaque) can be useful for WebDAV or not (it's not the case for WOPI), and in case we can still change the API later on as we are fleshing out the code both on WebDAV and WOPI.
@glpatcern When listing / stating files we may need to return the Locks on a resource. For this we should add an array of Locks to the ResourceInfo. What do you think? |
allow returning a list of Lock messages in ResourceInfo |
That would be welcome to avoid to blindly call |
@butonic but what is the meaning of having multiple locks for a given single resource? A priori |
Webdav allows shared locks .... |
As WOPI does, i.e. any user may alter a shared lock provided the write rights are there and the lock is |
Lat me just quote from http://www.webdav.org/specs/rfc2518.html#n-exclusive-vs.-shared-locks
We should probably learn from that ;-) Not for WOPI, but to let others know who is working on a file in the web ui. Maybe a WOPI app lock is best represented by one or multiple shared locks in WebDAV, which would allow listing who is collaborating? |
I like the idea of exposing who is in a WOPI collab session, which so far has been completely within the apps, not externalized. But I'd rather change the lock structure such that the lock metadata includes a list of users and is still a single entity - makes it easier for WOPI apps to refresh lock / unlock. Yet, I have to double check that the WOPI apps do refresh a lock when a new user joins a collab session, not sure they are requested to (but we'd have other ways to intercept that - the The whole structure would be then something like this?
|
I like that, let me update the pr ... |
Looks all good now, @ishank011 can you give a look too? I'm fine for merging this and then we can adapt cs3org/reva#2444 with @gmgigi96 as well. |
@glpatcern making these changes I still don't feel good about having only a single Lock property on the ResourceInfo. While it is true that you can only really have a single exclusive write lock on a file (which is a technical detail) the current data structures do not allow us to implement the WebDAV shared locks at all, because in WebDAV every lock has an Why do we even have the lock type SHARED if we can only set one lock? That does not make sense. When WOPI locks a file it will always lock it exclusively. That also works when a shared WebDAV lock exists. But in WebDAV land we have to be able to distinguish multiple locks, which is why every lock will get a dedicated When rereading https://docs.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/concepts#lock
So the X-WOPI-Lock is discoverable and we can expose it via WebDAV. The WOPI access_token obviously needs to be kept secret though.
AFAICT WOPI and WebDAV Locks are implemented by dedicated services. The WOPI docs already mention external locks. In order to build these services on top of the CS3 API we should
The implementation for now only needs to deal with exclusive write locks. And that is the only thing I need to implement right now. |
@glpatcern Ok, I defined a common Lock message that is used in the ResourceInfo twofold:
|
I hope this is good for @wkloucek and @ishank011 now as well. If so, merge pls ;-) |
Looks good, I see you came back to a single user for the exclusive lock as opposed to the list of users for a collab app. After all that's also fine - the lock is held by the app - but then why not going back to the |
I think a lock should be able to carry both: an app and the user. It is not an either or relationship. You could set advisory locks for different devices, eg to say that a user is viewing a file on his mobile or in the web ui. And for the write / exclusive lock it could be the user that list had edit permissions. IIRC @mmeeks mentioned that. I'm not 100% sure we need that but limiting it to oneof seems overly restrictive. |
The interesting thing is I also thought to have both Now I don't see a problem to keep both, and even enforcing |
Hehe, so I am coming from a UML tool developer perspective here: whenever you want to model something you need to allow inconsistent state in order to truly model the full lifecycle of objects. In this case, while an app may hold a WOPI lock, all users may have left the session ... then the user should be empty. I don't know if it is even possible to get that information out of the application. I admit we may have a different approach of building apis: I am trying to build a generic API that can transport different intenst, whereas you seem to try to already enforce limitations. But now I'm interested in why @wkloucek proposed the oneof? |
Ahah yes, seems like I'm trying to constrain what should not be done! For that scenario of an empty user, it is actually impossible: when the last user quits a collaborative session, the app unlocks the file. And even if the app forgets to unlock, the lock metadata is still semantically correct: it contains the user that last performed an action through the app. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are largely cosmetic changes, but by now you know I prefer a spelled out and more constrained behavior ;-)
Co-authored-by: Giuseppe Lo Presti <[email protected]>
Co-authored-by: Giuseppe Lo Presti <[email protected]>
@labkode @ishank011 hit merge unless you have any objections, pls. |
Co-authored-by: Giuseppe Lo Presti <[email protected]>
Regarding locks: how should a client make an upload, rename, delete, copy or move call when he locked a resource? AFAICT clients need to sent along the lock id in both WOPI (as We don't need to add that to this PR. But it is something I need to consider for the implementation. As does every storage driver implementation that wants to support locking. |
This makes perfect sense but like you said we don't need to add this for now. In particular, enforcing the LockID check via GRPC should be a development coordinated with extending the WOPI server to always pass down the line its WOPI id for its CS3 requests to Reva, otherwise the WOPI server would cut itself out after locking a file! So yes you should consider it for "your" implementation (as well as for our eos storage driver) but let's coordinate. That said, if no further comments I'll merge by lunch break. |
@glpatcern true, I'll add an implementation for the ocdav service in my PR for WebDAV locks. Like the wopi server it is a client to the GRPC CS3 api and needs to send the lockid with modifying requests. |
@glpatcern @wkloucek Setting just an mtime does not tell the server when it can release the lock. I propose we use a Timestamp to store the expiration timestamp instead. This would also align better with the WebDAV
Timeout
request header for the LOCK method: http://www.webdav.org/specs/rfc2518.html#rfc.section.9.8It also allows setting the 30min WOPI timeout, documented as MUST by https://docs.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/concepts#lock and https://docs.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/files/refreshlock