On 03/30/2010 06:50 AM, Caleb James DeLisle wrote:
>
>
> Sergiu Dumitriu wrote:
>> On 03/29/2010 06:57 PM, cjdelisle (SVN) wrote:
>>> Author: cjdelisle
>>> Date: 2010-03-29 18:57:58 +0200 (Mon, 29 Mar 2010)
>>> New Revision: 28004
>>>
>>> Modified:
>>>
>>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/Document.java
>>>
>>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/XWiki.java
>>> Log:
>>> XWIKI-5041: Allow script authors to load and save documents in their own
>>> security context, not the user's
>>
>> Quick review:
>>
>> 1. Although this is not always the case in the current API, methods
>> should not throw exceptions, since there is no way to catch them in
>> Velocity, and it's not nice at all to display exceptions and stacktraces
>> to the user. It would be better to catch all and return a boolean if the
>> save/delete fails.
> What should become of the exception?
> I have seen some very old code which put the exception in the context but I
> don't see that happening
> anywhere in the Document or XWiki API.
Yes,exceptions should be placed in the context.
> Is it right to eat the exception and return false?
Well, it's wrong to let the exception pass through. But since this
creates an API inconsistency, it should be discussed on a broader scope
(Proposal?).
>>
>> 2. I don't quite like the comments; with an empty mind, I wouldn't
>> understand what "the author of the code calling this function takes
>> responsibility" actually means. Maybe something like this would be better:
>>
>> Save the document under the privileges of the script's author. More
>> specifically, before saving, access rights are checked for the {...@link
>> #getContentAuthor content author} of the context document on the target
>> document, which also is set as the new author of the document.
>>
>> The comment for XWiki.getDocumentAsAuthor is quite good.
>>
>> Read below for more comments.
>>
>>> Modified:
>>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/Document.java
>>> ===================================================================
>>> ---
>>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/Document.java
>>> 2010-03-29 16:57:48 UTC (rev 28003)
>>> +++
>>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/Document.java
>>> 2010-03-29 16:57:58 UTC (rev 28004)
>>> @@ -1823,6 +1823,64 @@
>>> }
>>> }
>>>
>>> + /**
>>> + * Save the document, the author (contentAuthor) of the code calling
>>> this function takes responsibility.
>>> + * Saves with minorEdit set to false and no edit comment.
>>> + *
>>> + * @throws XWikiException if script author is not allowed to save the
>>> document or if save operation fails.
>>> + * @see #saveAsAuthor(String, boolean)
>>
>> 2.3M2 already.
> Thanks, changing.
>
>>
>>> + * @since 2.3M1
>>> + */
>>
>> public boolean saveAsAuthor()
>>
>>> + public void saveAsAuthor() throws XWikiException
>>> + {
>>> + saveAsAuthor("", false);
>>> + }
>>> +
>>> + /**
>>> + * Save the document, the author (contentAuthor) of the code calling
>>> this function takes responsibility.
>>> + * Saves with minorEdit set to false.
>>> + *
>>> + * @param comment The comment to display in document history (what did
>>> you change in the document)
>>> + * @throws XWikiException if script author is not allowed to save the
>>> document or if save operation fails.
>>> + * @see #saveAsAuthor(String, boolean)
>>> + * @since 2.3M1
>>> + */
>>> + public void saveAsAuthor(String comment) throws XWikiException
>>> + {
>>> + saveAsAuthor(comment, false);
>>> + }
>>> +
>>> + /**
>>> + * Save the document, the author (contentAuthor) of the code calling
>>> this function takes responsibility.
>>> + * This document will be saved if the author of the document
>>> containing the code which calls this function has
>>> + * edit access to it. The contentAuthor of this document will be set
>>> to the author of the calling script, not the
>>> + * viewer.
>>
>> This line doesn't make sense:
> I Will remove it.
>
>>
>>> + * It is unwise to allow this function to be called by the viewer of
>>> the script.
>>> + *
>>> + * @param comment The comment to display in document history (what did
>>> you change in the document)
>>> + * @param minorEdit Set true to advance the document version number by
>>> 0.1 or false to advance version to the next
>>> + * integer + 0.1 eg: 25.1
>>> + * @throws XWikiException if script author is not allowed to save the
>>> document or if save operation fails.
>>> + * @since 2.3M1
>>> + */
>>> + public void saveAsAuthor(String comment, boolean minorEdit) throws
>>> XWikiException
>>> + {
>>
>> I wonder if this is the best way to get the content author. What happens
>> with all the different include methods? Specifically, DocumentA includes
>> DocumentB (sheet or topic), the call is in DocumentB; what is the
>> context document?
> This was discussed:
> "momentarily switched to the content author of the document in the context"
> http://n2.nabble.com/Proposal-Add-APIs-to-get-and-save-document-in-the-security-context-of-the-author-of-the-script-which-td4791045.html
>
> I think that we should adhere to the standard procedure that
> #includeInContext and {{include context="default"}}
> makes the document stay the same, this is how programmingRights work and I
> don't think it is a security issue
> any more than velocity is a security problem because a script coder can say
> #evaluate($request.get('code'))
> and allow the viewer to run code.
>
> #includeTopic - Included document
> {{include context="new" Included document
>
> #includeInContext - Including document
> #includeForm - Including document
> {{include context="default" Including document
>
> I think discussion of changing this behavior should be part of the 2.0 API
> design.
Sure, I wasn't proposing a change, just wondering aloud.
>>> + String author = getXWikiContext().getDoc().getContentAuthor();
>>> + if (hasAccessLevel("edit", author)) {
>>> + String viewer = getXWikiContext().getUser();
>>> + try {
>>> + getXWikiContext().setUser(author);
>>> + saveDocument(comment, minorEdit);
>>> + } finally {
>>> + getXWikiContext().setUser(viewer);
>>> + }
>>> + } else {
>>> + java.lang.Object[] args = { author,
>>> getXWikiContext().getDoc(), this.doc.getFullName() };
>>> + throw new XWikiException(XWikiException.MODULE_XWIKI_ACCESS,
>>> XWikiException.ERROR_XWIKI_ACCESS_DENIED,
>>> + "Access denied; user {0}, acting through script in
>>> document {1} cannot save document {2}", null, args);
>>> + }
>>> + }
>>> +
>>> protected void saveDocument(String comment, boolean minorEdit)
>>> throws XWikiException
>>> {
>>> XWikiDocument doc = getDoc();
>>> @@ -1952,6 +2010,31 @@
>>> }
>>> }
>>>
>>> + /**
>>> + * Delete the document, the author (contentAuthor) of the code calling
>>> this function takes responsibility.
>>> + * It is unwise to allow this function to be called by the viewer of
>>> the script.
>>> + *
>>> + * @throws XWikiException if script author is not allowed to delete
>>> the document or if save operation fails.
>>> + * @since 2.3M1
>>> + */
>>> + public void deleteAsAuthor() throws XWikiException
>>> + {
>>> + String author = getXWikiContext().getDoc().getContentAuthor();
>>> + if (hasAccessLevel("delete", author)) {
>>> + String viewer = getXWikiContext().getUser();
>>> + try {
>>> + getXWikiContext().setUser(author);
>>> + deleteDocument();
>>> + } finally {
>>> + getXWikiContext().setUser(viewer);
>>> + }
>>> + } else {
>>> + java.lang.Object[] args = { author,
>>> getXWikiContext().getDoc(), this.doc.getFullName() };
>>> + throw new XWikiException(XWikiException.MODULE_XWIKI_ACCESS,
>>> XWikiException.ERROR_XWIKI_ACCESS_DENIED,
>>> + "Access denied; user {0}, acting through script in
>>> document {1} cannot delete document {2}", null, args);
>>> + }
>>> + }
>>> +
>>> public void deleteWithProgrammingRights() throws XWikiException
>>> {
>>> if (hasProgrammingRights()) {
>>>
>>> Modified:
>>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/XWiki.java
>>> ===================================================================
>>> ---
>>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/XWiki.java
>>> 2010-03-29 16:57:48 UTC (rev 28003)
>>> +++
>>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/XWiki.java
>>> 2010-03-29 16:57:58 UTC (rev 28004)
>>> @@ -172,6 +172,53 @@
>>> }
>>>
>>> /**
>>> + * Loads an Document from the database. Rights are checked on the
>>> author (contentAuthor) of the document
>>> + * containing the currently executing script before sending back the
>>> loaded document.
>>> + *
>>> + * @param fullName the full name of the XWiki document to be loaded
>>> + * @return a Document object or null if it is not accessible
>>> + * @throws XWikiException
>>> + * @since 2.3M1
>>> + */
>>> + public Document getDocumentAsAuthor(String fullName) throws
>>> XWikiException
>>> + {
>>> + DocumentReference reference;
>>> +
>>
>> This branching could be replaced by
>> ....resolve(StringUtils.defaultString(fullName);
> I copied the getDocument method and I think they ought to both be the same,
> I think resolve(StringUtils.defaultString(fullName) would create confusion as
> to
> what is actually happening and StringUtils is not currently included in
> api.XWiki
> which already has to many imports.
>
>>
>>> + // We ignore the passed full name if it's null to match behavior
>>> of getDocument
>>> + if (fullName != null) {
>>> + // Note: We use the CurrentMixed Resolver since we want to use
>>> the default page name if the page isn't
>>> + // specified in the passed string, rather than use the current
>>> document's page name.
>>> + reference =
>>> this.currentMixedDocumentReferenceResolver.resolve(fullName);
>>> + } else {
>>> + reference = this.defaultDocumentReferenceResolver.resolve("");
>>> + }
>>
>> Perhaps you mean:
>> return getDocumentAsAuthor(reference);
> Thanks for pointing that out, changing...
>
>>
>>> + return getDocument(reference);
>>> + }
>>> +
>>> + /**
>>> + * Loads an Document from the database. Rights are checked on the
>>> author (contentAuthor) of the document
>>> + * containing the currently executing script before sending back the
>>> loaded document.
>>> + *
>>> + * @param reference the reference of the XWiki document to be loaded
>>> + * @return a Document object or null if it is not accessible
>>> + * @throws XWikiException
>>> + * @since 2.3M1
>>> + */
>>> + public Document getDocumentAsAuthor(DocumentReference reference)
>>> throws XWikiException
>>> + {
>>> + String author = getXWikiContext().getDoc().getContentAuthor();
>>> + XWikiDocument doc = this.xwiki.getDocument(reference,
>>> getXWikiContext());
>>> + if (this.xwiki.getRightService().hasAccessLevel("view", author,
>>> doc.getFullName(),
>>
>> == false should be replaced by a !
> Will change.
>
>>
>>> + getXWikiContext()) == false) {
>>> + return null;
>>> + }
>>> +
>>> + Document newdoc = doc.newDocument(getXWikiContext());
>>> + return newdoc;
>>> + }
>>> +
>>> + /**
>>> * @param fullname the {...@link XWikiDocument#getFullName() name}
>>> of the document to search for.
>>> * @param lang an optional {...@link XWikiDocument#getLanguage()
>>> language} to filter results.
>>> * @return A list with all the deleted versions of a document in the
>>> recycle bin.
>>
--
Sergiu Dumitriu
http://purl.org/net/sergiu/
_______________________________________________
devs mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/devs