Hi everyone,
I am currently working on a project involving XWiki and I need to implement a feature that would allow me to lock a page, and then unlock it after some time (to prevent merge conflicts) using the REST API. I have gone through the API documentation but I can’t seem to find a direct way to perform this operation.
I’m aware that we can add page permissions using XWiki.XWikiRights objects to prevent page from being edited https://snippets.xwiki.org/xwiki/bin/view/Extension/Setting%20Rights. Essentially, I can make calls to custom API endpoints to add/remove the XWiki.XWikiRights objects to a page whenever I want to lock/unlock it. However, the problem I’m facing here is that every time I add or remove the object, XWiki creates a new entry in the page history. I want to avoid this because the page could potentially go through numerous lock/unlock cycles, which would clutter up the history.
My goal is to restrict the ability to modify certain pages once they reach a specific state, and to do this programmatically rather than manually through the user interface, all while maintaining a clean page history.
Is there a way to set a page’s permissions to “read only” through the API, or some other method of effectively ‘locking’ a page so that it cannot be edited, without creating a page history entry each time?
Any guidance on this would be hugely appreciated! If anyone has a snippet of code that does this or could point me in the direction of the relevant API calls, that would be fantastic.
Thanks in advance for your assistance!
For locking / unlocking a page see xwiki-platform/xwiki-platform-core/xwiki-platform-edit/xwiki-platform-edit-ui/src/main/resources/XWiki/InplaceEditing.xml at master · xwiki/xwiki-platform · GitHub but note that these locks can be forced, so it doesn’t guarantee that the page won’t be modified. A better approach is probably to write a document save listener that cancels / prevents the save based on some conditions. See https://extensions.xwiki.org/xwiki/bin/view/Extension/Observation+Module+Local .
Thanks for the suggestion. For our specific use case, a simple page lock should suffice, as long as I instruct users in our team not to force edit when the automation API user has locked the page. I dug through the XWiki documentation and found a more straightforward approach to implement this using setLock and removeLock methods.
SetPageLock, a child page of APIPages page:
{{groovy}}
import org.xwiki.model.reference.DocumentReference
def request = xcontext.getRequest()
def response = xcontext.getResponse()
def page = request.getParameter("page")
if (page != null && !page.isEmpty()) {
DocumentReference reference = new DocumentReference("xwiki", ['SpaceA', 'SpaceB', page], 'WebHome')
def context = xcontext.context
def xwiki = context.getWiki()
def doc = xwiki.getDocument(reference, context)
def setLock = doc.setLock("XWiki.automation-api-user", context)
}
{{/groovy}}
SetRemoveLock, a child page of APIPages page:
{{groovy}}
import org.xwiki.model.reference.DocumentReference
def request = xcontext.getRequest()
def response = xcontext.getResponse()
def page = request.getParameter("page")
if (page != null && !page.isEmpty()) {
DocumentReference reference = new DocumentReference("xwiki", ['SpaceA', 'SpaceB', page], 'WebHome')
def context = xcontext.context
def xwiki = context.getWiki()
def doc = xwiki.getDocument(reference, context)
def removeLock = doc.removeLock(context)
}
{{/groovy}}
Then I can make http requests to lock/unlock page like this, for example:
https://xwiki.local/bin/get/APIPages/SetPageLock/?page=the-page-to-be-edited&xpage=plain&outputSyntax=plain
and
https://xwiki.local/bin/get/APIPages/SetRemoveLock/?page=the-page-to-be-edited&xpage=plain&outputSyntax=plain